How to delete PrivateFontCollection.AddFontFile?

We create a large number of fonts for easy use. Fonts are embedded in documents. I want to delete font files if they are no longer in use. How can we do this? The following simplified code does not work:

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); 

Deleting a file is in error because the file is locked. What can I do to release the file lock?

PS: Before using AddMemoryFont. This works with Windows 7. But with Windows 8.NET, use the wrong font files after the first FontFamily has been removed. Since each document may contain different fonts, we need a very large number of fonts and cannot contain links to everything.

+5
source share
1 answer

After looking at the code of the AddFontFile method:

 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); } 

we see that the font is registered 2 times. First in GDI + and on the last line in GDI32. This is different from the AddMemoryFont method. In the Dispose method, it is not registered in GDI +. This leads to a leak in GDI32.

To compensate for this, you can call the following:

 [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int RemoveFontResourceEx(string lpszFilename, int fl, IntPtr pdv); pfc.AddFontFile(fontFile); RemoveFontResourceEx(fontFile, 16, IntPtr.Zero); 
+9
source

Source: https://habr.com/ru/post/977446/


All Articles