【发布时间】:2014-11-07 05:03:00
【问题描述】:
我最近在一个过去可以正常工作的程序中遇到问题。我追踪到以下代码:
using System.Drawing;
using System.Runtime.InteropServices;
namespace Foo
{
static class CProgram
{
[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetDefaultDllDirectories(int directoryFlags);
public const int LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x000001000;
private static void Main()
{
SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
Font font = SystemFonts.DefaultFont;
}
}
}
一旦我将 SetDefaultDllDirectories 用作参数而不是零,程序就会崩溃。我追踪到 SafeNativeMethods.Gdip.GdipGetGenericFontFamilySansSerif(out fontfamily);它简单地称为“GdipGetGenericFontFamilySansSerif”。但此调用失败并出现 FontFamilyNotFound 错误。
它可以在没有 SetDefaultDllDirectories 的情况下工作。如果我在调用之前和之后放置字体分配,它甚至可以工作。
我的系统上是否有任何东西导致了这个问题,或者是 MS 的更新导致了这个错误?
系统:Win7 x64,完全更新,AMD Radeon HD 使用最新的 beta 驱动程序
背景:我需要该函数来使用 AddDllDirectory 添加我的可执行文件路径的子目录(类似于 C:/MyProgram/myLibrariesX)
【问题讨论】:
-
Hmya,这是最糟糕的全局变量。 Gdiplus.dll 有两个版本,您基本上永远不会想要 system32 中的兼容版本,那就是龙。这是一个 XY 问题,它肯定比 that 有更好的答案。不仅限于避免故意给 Windows 带来麻烦,只需将 DLL 复制到正确的位置即可。
-
我同意汉斯的观点。换句话说,AFAIK,问题只是 .NET 不支持对 SetDefaultDllDirectories 的调用。
-
同意。你需要解决问题的根源。
-
用调试器查看加载的库显示,在这两种情况下,加载了来自 WinSxS 文件夹的相同 dll。目录的背景是,一个包含 x86 和一个 x64 dll。在启动时(使用“任何”架构编译)它会选择正确的文件夹来加载。还有很多 gstreamer 插件最好放在一个单独的文件夹中,而不是在一个文件夹中包含 100 个文件。跟进“.NET 不支持对 SetDefaultDllDirectories 的调用”:为什么?调用本身有效...当前解决方法:在使用该功能之前访问 SystemFonts.DefaultFont...
-
由于MS14-045/CVE-2014-1819,MS 最近改变了字体加载的工作方式。我不知道这是否与您的问题特别相关,但如果您想更深入地了解代码失败的确切原因,请尝试运行Process Monitor。
标签: .net winforms winapi fonts gdi