VC2008下提示找不到MSVCP90D.dll的解決辦法

VS 2005在生成可執行文件時使用了一種新的技術,該技術生成的可執行文件會伴隨生成一個清單文件(manifest file)(.manifest後綴文件)(其本質上是XML文檔,你可以用文本編輯器打開看看),並在鏈接完成後將該清單文件嵌入到exe文件中(默認情況下)。而在FAT32文件系統中,在處理清單文件階段,當增量鏈接時不能完成清單文件的更新(默認情況下),於是造成清單文件嵌入失敗,從而使該exe文件運行時沒有相應的清單文件而運行失敗並提示如上錯誤。

 

1. 好像是fat32下時間戳有問題(在ntfs下這個問題就沒有了),搞得manifest有時嵌入不到exe中(默認配置是嵌入的,所以就報錯找不到 dll了。

2. 磁盤系統是fat32格式的:FAT32的時間精度不夠,所以linker在生成文件的時候會出錯,如果是ntfs的就沒有問題


解決方案很多,列舉如下:
1. 由於這是在鏈接動態運行庫出現的問題,所以你可以選擇代碼生成的連接方式爲/MTd而非/MDd,不用這些DLL文件從而避免問題的出現。該方法有一個很顯然的缺點:適用範圍有限,不推薦該方法。
2. 既然跟FAT32系統有關,那麼我們可以選擇在NTFS文件系統中開發從而避免該問題,此方法同上,也是採用的迴避問題的方式,不提倡。
3. 該方法仍與FAT32有關:在項目的“屬性|配置屬性|清單工具|常規(Project | Game Properties | Configuration Properties | C/C++ | Code Generation | Runtime Library)”中的“使用FAT32解決辦法”選擇“是”(默認爲“否”),重新生成項目即可解決問題。該方法是唯一真正針對問題所在而提出的解決方法,使清單工具可以正確更新。(此方法是官方解決方法,也比較方便,推薦)
4. 既然問題是在更新嵌入的清單文件時發生的,由於FAT32的原因而未能更新嵌入的清單文件,於是我們有如下兩種解決方法:
(1)不啓用增量鏈接。在項目的“屬性|配置屬性|鏈接器|常規”中的“啓用增量鏈接”選擇“否”。此方法阻斷了問題產生的源頭,其每次生成exe文件時都直接嵌入清單文件,而不是默認的根據時戳而決定是否更新清單文件。
(2)不嵌入清單文件。在項目的“屬性|配置屬性|清單工具|輸入和輸出”中的“嵌入清單”選擇“否”,從而在生成exe文件時附隨生成一個清單文件(默認情況下,其文件名爲exe文件的全名加上“.manifest”),避免了嵌入清單文件可能失敗的問題。在程序運行時,會用到該清單文件。顯然,這種方式使可執行程序產生了更多的外部依賴,不推薦。

另外,還有一個不能稱爲方法的土辦法:每次Build前手動刪除*.ilk文件(增量鏈接文件)(當然可以在項目屬性中寫入刪除命令,使其自動執行),不推薦該土辦法。
最後,總結一下:
1. 此問題只在特定條件下才會出現:在FAT32文件系統中編譯、默認設置(增量模式、不啓用FAT32解決方案、嵌入清單文件)、非第一次生成可執行文件文件(即在增量連接、更新清單文件時)。
2. 解決方案1和4.1方便實用,推薦使用。

 

 

 

manifest原理和用途

dll是被動態調用的,所以會被若干個程序共享使用的 但是如果dll在應用程序不知道的情況下升級了、或是被另一個程序更改了,就可能會出現問題,即”DLL Hell”

隨着系統資源越來越豐富,硬盤不那麼緊張,所以在XP以後的操作系統中,用新的機制來管理DLL
(這種機制,這不僅僅是對於.NET而言,對於普通的Native程序也是一樣的)

Madifest是個XML的描述文件,對於每個DLL有DLL的Manifest文件,對於每個應用程序Application也有自己的Manifest

對於應用程序而言,Manifest可以是一個和exe文件同一目錄下的.manifest文件,也可以是作爲一個資源嵌入在exe文件內部的(Embed Manifest)

XP以前版本的windows,會像以前那樣執行這個exe文件,尋找相應的dll,沒有分別
Manifest只是個多餘的文件或資源,dll文件會直接到system32的目錄下查找,並且調用

而XP以後的操作系統,則會首先讀取Manifest,獲得exe文件需要調用的DLL列表
(此時獲得的,並不直接是DLL文件的本身的位置,而是DLL的manifest)
操作系統再根據DLL的Manifest去尋找對應的DLL
<因此就可能區別不同版本的同一個DLL文件,或是指定一個程序本身Isolated的DLL>

不過使用Visual Studio 2005以後的一個新問題是,
VS2005帶的8.0新版的C運行庫(VC 8.0 CRT)文件在XP以後支持manifest的Windows版本中被調用時,
將會check一下Application自身的Manifest,否則將會拒絕被調用
這也就是說,使用Visual Studio開發的Application,Manifest將是必不可少的
(搞不懂MS爲啥要這樣設置,所以與VS2003.NET不同了)
(後來想想,除了MS自己說的哪些冠冕堂皇的原因,至少這樣一來Linux的Wine模擬要麻煩多了)

除非,你的程序是靜態鏈接的,沒有使用dll,只使用了操作系統核心的 Kernel32.dll, User32.dll, Ole32.dll, 或ShDocVW.dll 等
project的設置必須是Use Standard Windows Libraries、Not Using ATL、No Common Language Runtime support

那麼你可以不需要考慮Manifest 可以關掉它

轉自:http://blog.csdn.net/sea_sharka_17/article/details/4176178

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章