2014-10-31 17 views
4

我們爲短時間使用創建大量的字體。字體嵌入在文檔中。我想刪除字體文件,如果不再使用。我們應該怎麼做?以下簡化代碼不起作用:如何刪除PrivateFontCollection.AddFontFile的文件?

PrivateFontCollection pfc = new PrivateFontCollection(); 
pfc.AddFontFile(fontFile); 
FontFamily family = pfc.Families[0]; 
Console.WriteLine(family.GetName(0)); 

family.Dispose(); 
pfc.Dispose(); 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 
File.Delete(fontFile); 

由於文件被鎖定,文件的刪除失敗。我還能做些什麼來釋放文件鎖? PS:在我們使用AddMemoryFont之前。這與Windows 7一起工作。但是,在第一個FontFamily被處置後,Windows 8 .NET使用錯誤的字體文件。因爲每個文檔都可以包含其他字體,所以我們需要大量的字體,並且不能容納所有字體。

+1

新增連接錯誤https://connect.microsoft.com/VisualStudio/feedback/details/1379843 – Peter 2015-05-29 14:00:28

回答

8

在尋找方法AddFontFile的代碼之後:

public void AddFontFile(string filename) 
{ 
    IntSecurity.DemandReadFileIO(filename); 
    int num = SafeNativeMethods.Gdip.GdipPrivateAddFontFile(new HandleRef(this, this.nativeFontCollection), filename); 
    if (num != 0) 
    { 
     throw SafeNativeMethods.Gdip.StatusException(num); 
    } 
    SafeNativeMethods.AddFontFile(filename); 
} 

我們看到,字體註冊2次。首先在GDI +和GDI32的最後一行。這與AddMemoryFont方法不同。在Dispose方法中,它只在GDI +中未註冊。這導致GDI32泄漏。

爲了彌補這一點,你可以撥打如下:

[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
public static extern int RemoveFontResourceEx(string lpszFilename, int fl, IntPtr pdv); 

pfc.AddFontFile(fontFile); 
RemoveFontResourceEx(tempFile, 16, IntPtr.Zero); 
+1

對於那些想知道有關「16」:這是FR_PRIVATE標誌。 – 2014-11-25 11:04:40

+1

如果我們應用您的修復,如果MS修復此錯誤會發生什麼? – Peter 2015-05-29 13:52:52

+1

@Peter如果刪除未添加的字體,沒有任何東西可以避難。你可以測試這個,如果你調用它2次。或者你在沒有AddFontFIle的情況下調用它。 – Horcrux7 2015-05-30 19:53:32