我正在尝试使用以下代码加载与打印机驱动程序一起安装在C:\Windows\System32\文件夹中的DLL:
LoadLibraryW(L"C:\\Windows\\System32\\MagAPI.dll");GetLastError()报告“找不到指定的模块”。如果我将DLL移出System32文件夹(例如C:\SomeFolder\MagAPI.dll),那么它将正常加载,因此看起来不像是DLL本身的问题。有没有什么奇怪的Windows安全功能可能会阻止我的应用程序加载它?这是我能想到的唯一一件事,但我找不到任何明确的答案。
下面是来自ShowSnaps的调试输出,它显示了它失败的地方:
1a8c:1fd4 @ 19006756 - LdrLoadDll - ENTER: DLL name: C:\Windows\system32\MagAPI.dll DLL path: C:\Windows\system32;C:\Windows\system;C:\Windows;.;<otherstuff>
1a8c:1fd4 @ 19006756 - LdrpLoadDll - ENTER: DLL name: C:\Windows\system32\MagAPI.dll DLL path: C:\Windows\system32;C:\Windows\system;C:\Windows;.;<otherstuff>
1a8c:1fd4 @ 19006756 - LdrpLoadDll - INFO: Loading DLL C:\Windows\system32\MagAPI.dll from path C:\Windows\system32;C:\Windows\system;C:\Windows;.;<otherstuff>
1a8c:1fd4 @ 19006756 - LdrpFindOrMapDll - ENTER: DLL name: C:\Windows\system32\MagAPI.dll DLL path: C:\Windows\system32;C:\Windows\system;C:\Windows;.;<otherstuff>
1a8c:1fd4 @ 19006756 - LdrpSearchPath - ENTER: DLL name: C:\Windows\system32\MagAPI.dll DLL path: C:\Windows\system32;C:\Windows\system;C:\Windows;.;<otherstuff>
1a8c:1fd4 @ 19006756 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\system32\MagAPI.dll
1a8c:1fd4 @ 19006756 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1a8c:1fd4 @ 19006756 - LdrpSearchPath - RETURN: Status: 0xc0000135
1a8c:1fd4 @ 19006756 - LdrpFindOrMapDll - RETURN: Status: 0xc0000135
1a8c:1fd4 @ 19006756 - LdrpLoadDll - RETURN: Status: 0xc0000135
1a8c:1fd4 @ 19006756 - LdrLoadDll - RETURN: Status: 0xc0000135发布于 2013-09-01 07:11:35
既然您提到您的应用程序是32位的,那么您正在加载的DLL也必须是32位的。
LoadLibrary()失败的可能原因是,您运行的是64位版本的Windows,但打印机驱动程序错误地将其32位动态链接库安装到了System32文件夹中,而不是SysWOW64文件夹中。
一些背景知识:在64位版本的Windows上,64位DLL放在System32文件夹中,32位DLL放在SysWOW64文件夹中。我知道这听起来应该是相反的,但不要让名称让您感到困惑;文件夹这样命名是出于向后兼容性的原因。SysWOW64文件夹应该对应用程序是透明的: Windows有一种称为文件系统重定向的功能,它使32位应用程序可以通过指定System32文件夹(就像它们总是那样)来加载32位DLL,即使DLL实际上在SysWOW64中也是如此。
另一方面,LoadLibrary()会简单地拒绝加载放在错误文件夹中的动态链接库。这可能就是您所看到的行为。
问题的真正解决方案是联系打印机制造商,并通知他们他们的驱动程序安装程序将其DLL放入64位Windows版本下的错误文件夹中。如果他们修复了这个问题,您的应用程序将开始正常工作,而无需对现有代码进行任何更改。
同时,您应该能够通过执行以下操作来解决您的问题:
%windir%\Sysnative中的DLL复制到您可以控制的已知文件夹中。(我建议您在%TEMP%中创建一个唯一名称的文件夹,并将DLL复制到该文件夹中)。注意:Sysnative是一个特殊的别名,它映射到本机系统文件夹,该文件夹是64位版本的Windows.LoadLibrary()下的System32,并将其传递给您在步骤1中创建的DLL副本的路径。如果您需要支持64位Windows XP,则上述解决方法可能不起作用,因为Sysnative别名仅在Windows Vista或更高版本上有效。另一种解决方法是手动绕过文件系统重定向:
Wow64DisableWow64FsRedirection()暂时禁用文件系统重定向。这将允许您的应用程序查看DLL中的真实内容,将DLL从System32.Wow64RevertWow64FsRedirection().LoadLibrary()控制文件系统重定向的某个已知文件夹,并将其传递给您在步骤2中创建的DLL副本的路径。请注意,如果您正在考虑调用Wow64DisableWow64FsRedirection()以使LoadLibrary()在不复制DLL的情况下工作,请不要费心:LoadLibrary()不会注意该设置。(我实际测试了它。)
更多信息:File System Redirector
https://stackoverflow.com/questions/18522102
复制相似问题