Could not load file or assembly '... ...' or one of its dependencies. 由於應用程式配置不正確,應用程式未能啟動 ...
兩個工程分別是 .net2005下的 C# 和 C++ , C++ 工程使用 C++/CLI 封裝了幾個功能函數並在 C# 工程中載入使用封裝類。在本地運行正常,但發布到其他機器上卻出現異常對話方塊:“ Could not load file or assembly '... ...' or one of its dependencies. 由於應用程式配置不正確,應用程式未能啟動。重新安裝應用程式可能會糾正這個問題。 ( Exception from HRESULT: 0x800736B1 ) ”。
這個錯誤看上去好像是 C++ DLL庫本身的問題,其實並不盡然。由於使用了混合模式編譯託管 DLL ,所以該 DLL 又會用到非託管的 CRT ( C Run-Time )庫。如果機器上沒有安裝這些被使用到的運行時組件,就會產生類似 HRESULT: 0x8007 的錯誤。最簡單的方法是下載安裝 Microsoft Visual C++ 2005 Redistributable Package (x86)以得到代碼運行所需的 msvcr80.dll 及 msvcm80.dll 等;也可以到系統硬碟下的 Program Files\Common Files\Merge Modules 目錄下找到包含 CRT 字樣的 msm 檔案,把這些檔案添加到你的安裝程式裡面可以達到同樣的效果;如果 C++ 產生的不是 dll 而是可執行檔的話,也可以按照微軟的說明直接把需要的dll拷貝到應用程式目錄下。更為細緻的分析說明可以參考這裡:Bootstrapper for the VC++ 2005 Redists (with MSI 3.1)。
要注意的是,如果你編譯 C++ 託管程式集的時候使用的是 Debug 配置的話,產生的 DLL 需要調用的就是 CRT 對應的 debug 版本( msvcr80d.dll 及 msvcm80d.dll 等 )而不是上面那些 Redistributable Package 裡面的檔案。這樣的話即使你使用任何一種方法去安裝那些執行階段程式庫檔案也還是同樣會得到錯誤異常對話方塊。瞭解產生的 DLL 到底是 Debug 還是 Release 版本最簡單的方法是用文字編輯器開啟該 DLL 檔案,找到以下類似的內容(一般位於檔案末尾處):
view plaincopy to clipboardprint?
- <assembly xmlns="urn:schemas-microsoft-com:asm.v1"
- manifestVersion="1.0">
- <dependency>
- <dependentAssembly>
- <assemblyIdentity type="win32"
- name="Microsoft.VC80.DebugCRT"
- version="8.0.50608.0"
- processorArchitecture="x86"
- publicKeyToken="1fc8b3b9a1e18e3b">
- </assemblyIdentity>
- </dependentAssembly>
- </dependency>
- </assembly>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"<br />manifestVersion="1.0"><br /><dependency><br /><dependentAssembly><br /><assemblyIdentity type="win32"<br />name="Microsoft.VC80.DebugCRT"<br />version="8.0.50608.0"<br />processorArchitecture="x86"<br />publicKeyToken="1fc8b3b9a1e18e3b"><br /></assemblyIdentity><br /></dependentAssembly><br /></dependency><br /></assembly>
如果看到 Microsoft.VC80.DebugCRT ,那說明該 dll Link的目標是 CRT的Debug版本,如果是 Microsoft.VC80.CRT 則 link 到再分發版本。當我在 VS.net2005 的 IDE 中通過批產生來產生 C# exe 和 C++ dll 的時候,如果當前的活動解決方案配置是 Debug 的話,在 C# 項目的Release輸出目錄下拷貝的會是 C++ dll 的 Debug 版本檔案而不是 Release 版本!所以在發布產生之後確認對應檔案的版本還是相當有必要的。
另一個可能性是如果你的硬碟分區為 FAT32 格式的話, VS.net 在編譯 C++ dll 的時候有可能會因為時間戳記計算的失誤而沒有把正確的 Manifest 資訊(基本上就是上面提到的那部分 xml 配置資訊)寫到 dll 裡面,導致程式運行時得不到正確的 dependency 資訊產生載入錯誤。所以如果上述操作仍然無法解決錯誤的話,考慮在“屬性->配置屬性->清單工具->常規”下把“使用FAT32解決辦法”選項設定為"是"。