首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LoadLibraryW()无法在System32中加载DLL

LoadLibraryW()无法在System32中加载DLL
EN

Stack Overflow用户
提问于 2013-08-30 06:41:22
回答 1查看 11.4K关注 0票数 3

我正在尝试使用以下代码加载与打印机驱动程序一起安装在C:\Windows\System32\文件夹中的DLL:

代码语言:javascript
复制
LoadLibraryW(L"C:\\Windows\\System32\\MagAPI.dll");

GetLastError()报告“找不到指定的模块”。如果我将DLL移出System32文件夹(例如C:\SomeFolder\MagAPI.dll),那么它将正常加载,因此看起来不像是DLL本身的问题。有没有什么奇怪的Windows安全功能可能会阻止我的应用程序加载它?这是我能想到的唯一一件事,但我找不到任何明确的答案。

下面是来自ShowSnaps的调试输出,它显示了它失败的地方:

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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版本下的错误文件夹中。如果他们修复了这个问题,您的应用程序将开始正常工作,而无需对现有代码进行任何更改。

同时,您应该能够通过执行以下操作来解决您的问题:

  1. 在尝试加载DLL之前,请将%windir%\Sysnative中的DLL复制到您可以控制的已知文件夹中。(我建议您在%TEMP%中创建一个唯一名称的文件夹,并将DLL复制到该文件夹中)。注意:Sysnative是一个特殊的别名,它映射到本机系统文件夹,该文件夹是64位版本的Windows.
  2. Call LoadLibrary()下的System32,并将其传递给您在步骤1中创建的DLL副本的路径。
  3. 使用完DLL后,卸载它并删除您在步骤1中创建的副本。

如果您需要支持64位Windows XP,则上述解决方法可能不起作用,因为Sysnative别名仅在Windows Vista或更高版本上有效。另一种解决方法是手动绕过文件系统重定向:

  1. 通过调用Wow64DisableWow64FsRedirection()暂时禁用文件系统重定向。这将允许您的应用程序查看DLL中的真实内容,将DLL从System32.
  2. Copy over.
  3. Reenable复制到您通过调用Wow64RevertWow64FsRedirection().
  4. Call LoadLibrary()控制文件系统重定向的某个已知文件夹,并将其传递给您在步骤2中创建的DLL副本的路径。
  5. 使用完DLL后,卸载它并删除您在步骤2中创建的副本。

请注意,如果您正在考虑调用Wow64DisableWow64FsRedirection()以使LoadLibrary()在不复制DLL的情况下工作,请不要费心:LoadLibrary()不会注意该设置。(我实际测试了它。)

更多信息:File System Redirector

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18522102

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档