2013-08-29 32 views
2

我試圖加載安裝與在C打印機驅動程序DLL:\ WINDOWS \ SYSTEM32 \文件夾下面的代碼:LoadLibraryW()無法加載DLL在System32中

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 
+0

你在什麼版本的Windows?您可能需要管理員權限才能查看System32的內容。你可以做的快速測試是右鍵單擊並以管理員身份運行你的應用程序(win vista及以上,我認爲),如果它的工作,那就是問題所在。 –

+0

@JesusRamos我已經證實,該DLL在該文件夾中的確切路徑,如果這就是你問的。 – Shenjoku

+0

不,我要求您確認它是否是權限問題。有時從代碼訪問System32需要正在運行的應用程序的管理權限,即使只是讀取文件。 –

回答

4

既然你提到你的應用是32位的,你正在加載也必須是32位的DLL。

可能的原因LoadLibrary()失敗是你正在運行的Windows的64位版本,但您的打印機驅動程序安裝錯誤有關其32位DLL到System32文件夾,而不是SysWOW64文件夾。

一些背景:在64位版本的Windows上,64位DLL進入System32文件夾,並且32位DLL進入SysWOW64文件夾。我知道這聽起來應該是相反的方式,但不要讓名字混淆你;這些文件夾的名稱就像是出於向後兼容性的原因。 SysWOW64文件夾對於應用程序應該是透明的:Windows具有稱爲文件系統重定向的功能,通過指定System32文件夾(就像它們總是有的那樣),使32位應用程序可以加載32位DLL,即使DLL實際上在SysWOW64之內。

另一方面,LoadLibrary()將簡單地拒絕加載已放置在錯誤文件夾內的DLL。這是你可能看到的行爲。

問題的真正解決方案是聯繫打印機制造商,並通知他們他們的驅動程序安裝程序正在將其DLL放入64位版本的Windows下的錯誤文件夾中。如果他們解決了這個問題,那麼您的應用程序將會正常開始工作,而不會對現有代碼進行任

在此期間,你應該能夠這樣做是爲了解決你的問題:

  1. 在嘗試加載DLL,從%windir%\Sysnative複製DLL來,你可以控制一些已知的文件夾中。 (我建議你在%TEMP%內部創建一個唯一命名的文件夾,並將該DLL複製到該文件夾​​中)。注意:Sysnative是映射到本機系統文件夾的一個特殊別名,該文件夾在Windows的64位版本下爲System32
  2. 呼叫LoadLibrary(),並通過它的DLL的副本,您在步驟1
  3. 做當你正在使用的DLL完成的路徑,將其卸載並刪除您在步驟作出的副本1.

如果您需要支持64位Windows XP,上述解決方法可能不起作用,因爲Sysnative別名記錄爲僅在Windows Vista或更高版本上可用。另一種解決方法是手動繞過文件系統重定向:

  1. 通過調用Wow64DisableWow64FsRedirection()臨時禁用文件系統重定向。這將允許您的應用程序在System32中看到究竟是
  2. 將DLL從System32複製到某個已知文件夾,您可以控制該文件夾。
  3. 通過調用Wow64RevertWow64FsRedirection()重新啓用文件系統重定向。
  4. 呼叫LoadLibrary(),並通過它的DLL的副本,您在步驟2
  5. 做當你正在使用的DLL完成的路徑,將其卸載並刪除您在步驟作出的副本2.

請注意,如果您想撥打Wow64DisableWow64FsRedirection()以使LoadLibrary()無需複製DLL即可工作,請不要打擾:LoadLibrary()不會注意該設置。 (我實際測試過它)。

更多信息:File System Redirector