2014-10-29 7 views
6

나는 PrivateFontCollection 반환하는 함수가 있습니다.NET PrivateFontCollection는 - 파일 잠금을 해제하는 방법이 완료되면

Using customFonts = Common.GetCustomFonts() 
    ' Do some stuff here 
End Using 

나는 것으로 기대를 다음과 같이

Public Shared Function GetCustomFonts() As PrivateFontCollection 
    Dim result = New PrivateFontCollection 

    Dim customFontFiles = {"Garamond.TTF", "Garamond-Bold.TTF", "Garamond-Italic.TTF", "EurostileExtended-Roman-DTC.TTF"} 

    For Each fontFile In customFontFiles 
     result.AddFontFile(Hosting.HostingEnvironment.MapPath("/Includes/" & fontFile)) 
    Next 

    Return result 
End Function 

내가 그 기능을 사용을 파일이 릴리스되지만 여전히 잠겨 있습니다. 다음 오류가 발생합니다. '파일이 시스템에 열려 있기 때문에 작업을 완료 할 수 없습니다. 파일을 닫고 다시 시도하십시오. '

IIS에서 웹 사이트를 종료해도 도움이되지 않습니다. 우리는 풀을 풀기 위해 앱 풀을 재활용해야합니다.

누구나 파일이 inbetween 용도로 출시되는 방식으로 PrivateFontCollection을 사용하는 방법에 대해 조언 할 수 있습니까?

+0

지금까지 생각한 유일한 아이디어는 글꼴을 메모리에로드하고 AddMemoryFont를 사용하는 것입니다. 그렇게하면 PrivateFontCollection이 파일을 절대 닿지 않도록 보장 할 수 있습니다. – extremeandy

+0

가능한 답변은 http://stackoverflow.com/questions/26671026/how-to-delete-the-file-of-a-privatefontcollection-addfontfile – Horcrux7

+0

을 참조하십시오. 연결 버그 https://connect.microsoft.com/가 추가되었습니다. VisualStudio/feedback/details/1379843 – Peter

답변

1

해결 방법으로 글꼴을 메모리에로드하고 대신 'AddMemoryFont'를 사용했습니다. 아래 코드를 참조하십시오. 내가 .NET에서 관리되지 않는 리소스를 건드린 것은 이번이 처음이므로, 아래의 메모리 관리가 정상적으로 작동한다는 것을 보장 할 수는 없습니다.

Imports System.Drawing.Text 
Imports System.Runtime.InteropServices 

Public Class CustomFontService 
    Implements IDisposable 

    Dim _fontBuffers As List(Of IntPtr) 
    Dim _collection As PrivateFontCollection 

    Public Sub New() 
     _collection = New PrivateFontCollection 
     _fontBuffers = New List(Of IntPtr) 

     Dim customFontFiles = {"Garamond.TTF", "Garamond-Bold.TTF", "Garamond-Italic.TTF", "EurostileExtended-Roman-DTC.TTF"} 

     For Each fontFile In customFontFiles 
      Dim fontBytes = System.IO.File.ReadAllBytes(Hosting.HostingEnvironment.MapPath("/Includes/" & fontFile)) 

      Dim fontBuffer As IntPtr = Marshal.AllocHGlobal(fontBytes.Length) 
      Marshal.Copy(fontBytes, 0, fontBuffer, fontBytes.Length) 

      _fontBuffers.Add(fontBuffer) 

      _collection.AddMemoryFont(fontBuffer, fontBytes.Length) 
     Next 
    End Sub 

    Public Function GetCustomFonts() As PrivateFontCollection 
     Return _collection 
    End Function 

#Region "IDisposable Support" 
    Private disposedValue As Boolean ' To detect redundant calls 

    ' IDisposable 
    Protected Overridable Sub Dispose(disposing As Boolean) 
     If Not Me.disposedValue Then 
      If disposing Then 
       ' TODO: dispose managed state (managed objects). 
      End If 

      For Each buf In _fontBuffers 
       If (buf <> IntPtr.Zero) Then 
        Marshal.FreeHGlobal(buf) 
       End If 
      Next 

      ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below. 
      ' TODO: set large fields to null. 
     End If 
     Me.disposedValue = True 
    End Sub 

    ' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources. 
    Protected Overrides Sub Finalize() 
     ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above. 
     Dispose(False) 
     MyBase.Finalize() 
    End Sub 

    ' This code added by Visual Basic to correctly implement the disposable pattern. 
    Public Sub Dispose() Implements IDisposable.Dispose 
     ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above. 
     Dispose(True) 
     GC.SuppressFinalize(Me) 
    End Sub 
#End Region 

End Class