在VS 2005中建立Win32工程時(以VS 2005中文版為例),你可能會遇到這樣的運行錯誤:“沒有找到MSVCP80D.dll,因此這個應用程式未能啟動。重新安裝應用程式可能會修複此問題。”(還可能是其它幾個類似的檔案:MSVCR80D.dll、MSVCM80D.dll)。對於VS2005新手,可能遇到的第一個問題便是此問題。
一直使用VC6進行開發測試,最近準備把平台轉移到VS2005了。於是,決定先把CppUnit轉移到此平台上來。在VS2005中編譯CppUnit所遇到的問題不多,雖然沒VC6方便。但是在測試編譯好的CppUnit庫時卻遇到了困難:把以前在VC6中寫的AES移植過來(其使用了CppUnit進行單元測試),在運行時卻遇到了如上錯誤。剛開始以為可能是CppUnit沒有編譯好,重新編譯CppUnit多次,調整編譯參數,但始終有此錯誤,並且此錯誤有時出現有時不出現,這更暈了,大量時間就這樣浪費了。等我靜下來,才覺得可能是VS 2005的原因,於是上網搜尋此錯誤資訊,終於找到了問題所在。
VS 2005在產生可執行檔時使用了一種新的技術,該技術產生的可執行檔會伴隨產生一個資訊清單檔(manifest file)(.manifest尾碼檔案)(其本質上是XML文檔,你可以用文字編輯器開啟看看),並在連結完成後將該資訊清單檔嵌入到exe檔案中(預設情況下)。而在FAT32檔案系統中,在處理資訊清單檔階段,當增量連結時不能完成資訊清單檔的更新(預設情況下),於是造成資訊清單檔嵌入失敗,從而使該exe檔案運行時沒有相應的資訊清單檔而運行失敗並提示如上錯誤。
解決方案很多,列舉如下:
1. 由於這是在連結動態運行庫出現的問題,所以你可以選擇代碼產生的串連方式為/MTd而非/MDd,不用這些DLL檔案從而避免問題的出現。該方法有一個很顯然的缺點:適用範圍有限,並且也不是我等提倡的解決問題的方式,不推薦該方法。
2. 既然跟FAT32系統有關,那麼我們可以選擇在NTFS檔案系統中開發從而避免該問題,此方法同上,也是採用的迴避問題的方式,不為我等提倡。
3. 該方法仍與FAT32有關:在項目的“屬性|配置屬性|清單工具|常規”中的“使用FAT32解決辦法”選擇“是”(預設為“否”),重建項目即可解決問題。該方法是唯一真正針對問題所在而提出的解決方案,使清單工具可以正確更新。(此方法是官方解決方案,也比較方便,推薦)
4. 既然問題是在更新嵌入的資訊清單檔時發生的,由於FAT32的原因而未能更新嵌入的資訊清單檔,於是我們有如下兩種解決方案:
(1)不啟用增量連結。在項目的“屬性|配置屬性|連結器|常規”中的“啟用增量連結”選擇“否”。此方法阻斷了問題產生的源頭,其每次產生exe檔案時都直接嵌入資訊清單檔,而不是預設的根據時戳而決定是否更新資訊清單檔。
(2)不嵌入資訊清單檔。在項目的“屬性|配置屬性|清單工具|輸入和輸出”中的“嵌入清單”選擇“否”,從而在產生exe檔案時附隨產生一個資訊清單檔(預設情況下,其檔案名稱為exe檔案的全名加上“.manifest”),避免了嵌入資訊清單檔可能失敗的問題。在程式運行時,會用到該資訊清單檔。顯然,這種方式使可執行程式產生了更多的外部依賴,不推薦。
另外,還有一個不能稱為方法的土辦法:每次Build前手動刪除*.ilk檔案(增量連結檔案)(當然可以在項目屬性中寫入刪除命令,使其自動執行),不推薦該土辦法。
最後,總結一下:
1. 此問題只在特定條件下才會出現:在FAT32檔案系統中編譯、預設設定(增量模式、不啟用FAT32解決方案、嵌入資訊清單檔)、非第一次產生可執行檔檔案(即在增量串連、更新資訊清單檔時)。
2. 解決方案1和4.1方便實用,推薦使用。