我有一个 .NET 3.5 应用程序,它使用 PrivateFontCollection.AddMemoryFont 将字体加载到内存中并使用它们来生成图像。我最近在 Windows Server 2012 R2 上安装了它,它正在产生间歇性错误。
这个方法说明了这个问题:
private Bitmap getImage(byte[] fontFile)
{
using (PrivateFontCollection fontCollection = new PrivateFontCollection())
{
IntPtr fontBuffer = Marshal.AllocCoTaskMem(fontFile.Length);
Marshal.Copy(fontFile, 0, fontBuffer, fontFile.Length);
fontCollection.AddMemoryFont(fontBuffer, fontFile.Length);
Bitmap image = new Bitmap(200, 50);
using (Font font = new Font(fontCollection.Families[0], 11f, FontStyle.Regular))
{
using (Graphics graphics = Graphics.FromImage(image))
{
graphics.DrawString(String.Format("{0:HH:mm:ss}", DateTime.Now), font, Brushes.White, new PointF(0f, 0f));
}
}
return image;
}
}
在 Windows 7 上,这始终有效。在 Windows Server 2012 R2 上,如果使用不止一种字体重复调用它会失败。例如:
getImage(File.ReadAllBytes("c:\\Windows\\Fonts\\Arial.ttf"));
即使调用了数百次,但使用不止一种字体调用:
getImage(File.ReadAllBytes("c:\\Windows\\Fonts\\Wingding.ttf"));
getImage(File.ReadAllBytes("c:\\Windows\\Fonts\\Arial.ttf"));
将适用于前几次调用(大约 20 个),但随后会开始产生随机结果(第二次调用有时会返回一个带有侧翼文本的图像 - 即它混合了字体)。
我也偶尔(很少)在 DrawString 调用中收到“GDI+ 中发生一般错误”。
这些错误都不会在 Windows 7 上发生。
我尝试了各种清理方法,但都没有成功。
作为一种解决方法,我尝试将字体文件写入磁盘,然后使用 AddFontFile 加载,但是(在 Windows 2012 R2 上)字体文件在整个过程中被锁定,因此无法删除。这使得这个选项不可接受。
任何有关使 AddMemoryFont 始终如一地工作或让 AddFontFile 解锁文件的帮助,将不胜感激。