GetFontData 在 ASP.NET 应用程序中返回 -1 (GDI_ERROR),但在控制台应用程序中不返回。什么可能导致这种情况?

发布于 2024-11-10 01:49:34 字数 2007 浏览 2 评论 0原文

我们在其中一个 Web 应用程序中使用 PDFSharp(GDI+ 版本)。在一个 PDF 导出器中,我们使用非系统 truetype 字体,它在我们的开发环境中工作起来就像一个魅力,但当我们在生产中运行它时会崩溃。

我们的开发和生产之间的主要区别(我认为)是我们的生产服务器在 Windows Server 2008 64 位上运行,而我们的开发服务器在 2008 32 位上运行。我写了一个小测试程序来调试。

try
{
    new XFont("ocrb10", 10, XFontStyle.Regular, new XPdfFontOptions(PdfFontEncoding.Unicode, PdfFontEmbedding.Always));
}
catch (Exception exc) { Console.WriteLine(exc.StackTrace); }

错误消息为 InvalidOperationException:内部错误。无法检索字体数据。

at PdfSharp.Fonts.OpenType.FontData.CreateGdiFontImage(XFont font, XPdfFontOptions options)
at PdfSharp.Fonts.OpenType.FontData..ctor(XFont font, XPdfFontOptions options)
at PdfSharp.Fonts.OpenType.OpenTypeDescriptor..ctor(XFont font, XPdfFontOptions options)
at PdfSharp.Fonts.OpenType.OpenTypeDescriptor..ctor(XFont font)
at PdfSharp.Fonts.FontDescriptorStock.CreateDescriptor(XFont font)
at PdfSharp.Drawing.XFont.get_Metrics()
at PdfSharp.Drawing.XFont.Initialize()
at PdfSharp.Drawing.XFont..ctor(String familyName, Double emSize, XFontStyle style, XPdfFontOptions pdfOptions)

我从源代码构建了 PDFSharp 并添加了一些调试代码以了解发生了什么。问题在于 pinvoke 调用 GetFontData 返回 -1 (GDI_ERROR)。 PdfSharp 作者在 FontData.cs 中添加了对此的评论,其中错误发生(搜索 GDI_ERROR),但他也没有找到正确的解决方案。

// Line 138 in FontData.cs, this GetFontData returns -1 here when 
// running as a web application on a 64bit windows host (regardles of WOW64
// being enabled or not)
int size = NativeMethods.GetFontData(hdc, 0, 0, null, 0);

现在,我的问题是,当我将代码作为控制台应用程序运行时,我无法在任何环境中重现此错误。我尝试过打开和关闭应用程序池的 WOW64,并且尝试在自己的凭据下运行应用程序池,以防出现任何与权限相关的问题,但无济于事。

顺便说一句,PDFSharp 的 WPF 版本运行得很好,如果我们找不到任何解决方案,我们很可能会切换到该版本,但我真的很好奇可能会导致这种情况。

任何人都可以帮助我进一步的调试步骤吗?就 PInvoke 而言,在 IIS/ASP.NET 中运行时的环境与在控制台应用程序中运行时的环境有何不同?

We use PDFSharp (the GDI+ build) in one of our web applications. In one PDF exporter we're using a non-system truetype font and it works like a charm in our dev environment but crashes when we run it in production.

The key difference (I think) between our dev and production is that our production servers are running on Windows Server 2008 64bit while our dev is running 2008 32bit. I wrote a tiny test program to debug.

try
{
    new XFont("ocrb10", 10, XFontStyle.Regular, new XPdfFontOptions(PdfFontEncoding.Unicode, PdfFontEmbedding.Always));
}
catch (Exception exc) { Console.WriteLine(exc.StackTrace); }

The error message is InvalidOperationException: Internal error. Font data could not retrieved.

at PdfSharp.Fonts.OpenType.FontData.CreateGdiFontImage(XFont font, XPdfFontOptions options)
at PdfSharp.Fonts.OpenType.FontData..ctor(XFont font, XPdfFontOptions options)
at PdfSharp.Fonts.OpenType.OpenTypeDescriptor..ctor(XFont font, XPdfFontOptions options)
at PdfSharp.Fonts.OpenType.OpenTypeDescriptor..ctor(XFont font)
at PdfSharp.Fonts.FontDescriptorStock.CreateDescriptor(XFont font)
at PdfSharp.Drawing.XFont.get_Metrics()
at PdfSharp.Drawing.XFont.Initialize()
at PdfSharp.Drawing.XFont..ctor(String familyName, Double emSize, XFontStyle style, XPdfFontOptions pdfOptions)

I built PDFSharp from source and added some debug code in order to understand what's happening. The problem is that the pinvoke call to GetFontData returns -1 (GDI_ERROR). The PdfSharp author has added comments about this in FontData.cs where the error occurrs (search for GDI_ERROR) but he didn't find a proper resolution either.

// Line 138 in FontData.cs, this GetFontData returns -1 here when 
// running as a web application on a 64bit windows host (regardles of WOW64
// being enabled or not)
int size = NativeMethods.GetFontData(hdc, 0, 0, null, 0);

Now, the problem for me is that I am unable to reproduce this error in any environment when I run the code as an console application. I've tried toggling WOW64 on and off for the application pool and I've tried running the application pool under my own credentials in case there was any permission related problems but to no avail.

The WPF build of PDFSharp works great btw and it's quite possible that we'll just switch to that if we don't find any solution but I'm really curious as to what could cause this.

Can anyone please help me with further debugging steps? In what ways are the environment different when running in IIS/ASP.NET versus a console application when it comes to PInvokes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哎呦我呸! 2024-11-17 01:49:34

开发人员通常依赖 GDI+ 来检索字体规格,但是 根据 MSDN

GDI+ 函数和类不是
支持在 Windows 中使用
服务。尝试使用这些
Windows 中的函数和类
服务可能会产生意想不到的结果
问题,例如服务减少
性能和运行时异常或
错误。

在 FontData.cs 中,我发现了以下内容:

#if GDI
100    /// <summary>
101    /// Create the font image using GDI+ functionality.
102    /// </summary>
103    void CreateGdiFontImage(XFont font, XPdfFontOptions options/*, XPrivateFontCollection privateFontCollection*/)
104    {
105      System.Drawing.Font gdiFont = font.RealizeGdiFont();
106      NativeMethods.LOGFONT logFont;
...

这就是为什么 PDFSharp 的 GDI+ 构建无法在服务中工作,而 WPF 构建却可以按照您在问题中所述的那样工作。

It is very common for developers to rely on GDI+ for retrieving font metrics, however according to MSDN:

GDI+ functions and classes are not
supported for use within a Windows
service. Attempting to use these
functions and classes from a Windows
service may produce unexpected
problems, such as diminished service
performance and run-time exceptions or
errors.

In FontData.cs I found the following:

#if GDI
100    /// <summary>
101    /// Create the font image using GDI+ functionality.
102    /// </summary>
103    void CreateGdiFontImage(XFont font, XPdfFontOptions options/*, XPrivateFontCollection privateFontCollection*/)
104    {
105      System.Drawing.Font gdiFont = font.RealizeGdiFont();
106      NativeMethods.LOGFONT logFont;
...

This is why GDI+ build of PDFSharp is not working in services while the WPF build does work as you stated on your question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文