參考資料: 應(yīng)用程序配置不正確,程序無(wú)法啟動(dòng) 的解決方法資料收集 內(nèi)容我就不copy了,大家可以自己去看,總來(lái)說(shuō)產(chǎn)生這個(gè)問(wèn)題的原因可以歸結(jié)如下: vc2005/vc2008采用了新的程序部署技術(shù)(manifest清單文件),manifest清單文件實(shí)際上類(lèi)似于我們常用的makefile文件,它定義了程序運(yùn)行的依賴(lài)關(guān)系(程序運(yùn)行所需要的dll庫(kù)的名稱(chēng)、版本等)。 程序運(yùn)行,首先根據(jù)manifest清單文件(這個(gè)文件可以嵌入到exe或dll中,或者單獨(dú)生成外部文件,可以通過(guò)vc2005/vc2008的編譯選項(xiàng)控制:工程“屬性”->“配置屬性”->“清單工具”->“輸入輸出”->“嵌入清單文件”,選擇“是”或“否”來(lái)控制)來(lái)查找程序運(yùn)行需要的dll庫(kù)的名稱(chēng)、版本等,如果所在的系統(tǒng)中沒(méi)有程序運(yùn)行所需要的dll庫(kù)和相應(yīng)的manifest清單文件,則彈出“應(yīng)用程序配置不正確,程序無(wú)法啟動(dòng)”對(duì)話框。 另外要注意,由于vc2005/vc2008與.net集成,導(dǎo)致出現(xiàn)一個(gè)新的概念:在.net中,將exe、dll都看成“程序集(assemble)”,每個(gè)程序集(assemble)都附帶有一個(gè)manifest清單文件,因此使得vc2005/vc2008的CRT(C 運(yùn)行時(shí)庫(kù))、MFC、ATL等dll庫(kù)都附帶有一個(gè)manifest清單文件。 歸根結(jié)底是由于老版本的系統(tǒng)沒(méi)有我們開(kāi)發(fā)的程序運(yùn)行所需要的基本運(yùn)行時(shí)庫(kù)(2k、xp系統(tǒng)只有vc6的一些dll庫(kù),而沒(méi)有vc2005、vc2008所需要的dll庫(kù)以及相應(yīng)的manifest清單文件,而在vista系統(tǒng)或者即將到來(lái)的windows 7系統(tǒng)上則包含有vc2005、vc2008的dll庫(kù)和manifest清單文件) ps:上面的那段話說(shuō)的有點(diǎn)幼稚和簡(jiǎn)單了,這里涉及到很多的問(wèn)題:程序的升級(jí)更新、vs的補(bǔ)丁、庫(kù)的版本問(wèn)題等等,不是簡(jiǎn)單的拷貝、粘貼就能解決的。。。
舉個(gè)例子:(在XP SP3系統(tǒng)下)
使用vc2008 express sp1版(沒(méi)有mfc、atl),新建一個(gè)“HelloWorld”的“win32控制臺(tái)應(yīng)用程序”工程,在release下編譯,此時(shí)默認(rèn)的編譯選項(xiàng):(在這里我們只關(guān)注與我們的問(wèn)題相關(guān)的幾個(gè)選項(xiàng)) 1、工程“屬性”->“配置屬性”->“c/c++”->“代碼生成”->“運(yùn)行庫(kù)” 默認(rèn)選項(xiàng)為/MD(release)、/MDd(debug),對(duì)這幾個(gè)編譯選項(xiàng)不清楚的可以參見(jiàn): VC運(yùn)行庫(kù)版本不同導(dǎo)致鏈接.LIB靜態(tài)庫(kù)時(shí)發(fā)生重復(fù)定義問(wèn)題的一個(gè)案例分析和總結(jié) 2、工程“屬性”->“配置屬性”->“清單工具”->“輸入輸出”->“嵌入清單文件” 默認(rèn)選項(xiàng)為“是”(表示將manifest清單文件嵌入到程序中);當(dāng)然,我們也可以選擇“否”,從而單獨(dú)生成一個(gè)manifest清單文件,不過(guò)這會(huì)增加不必要的依賴(lài)項(xiàng),因此不建議選擇“否”。 編譯->鏈接之后在“ HelloWorld ”工程的release或debug目錄下,我們能夠看到一個(gè)HelloWorld.exe.intermediate.manifest清單文件(根據(jù)編譯選項(xiàng),見(jiàn)上,vc2008將manifest清單文件嵌入到了exe程序中,HelloWorld.exe.intermediate.manifest清單文件是一個(gè)臨時(shí)文件,但它的內(nèi)容與嵌入到exe程序的manifest文件是一樣的),用文本編輯器打開(kāi)該文件(用“記事本”也行,不過(guò)格式太亂,看不清楚內(nèi)容,推薦使用vim或其它的文本編輯器查看),大致內(nèi)容如下: ps:在網(wǎng)上看到另外的一個(gè)方法,用記事本打開(kāi)exe或dll程序,查看嵌入到exe或dll中的manifest清單文件,方法:“打開(kāi)記事本,然后將exe或dll拖入到記事本中,當(dāng)然了,肯定會(huì)出現(xiàn)大段的亂碼,沒(méi)關(guān)系,直接往后看,就能發(fā)現(xiàn)類(lèi)似于下面的內(nèi)容的部分” XML語(yǔ)言: HelloWorld.exe.intermediate.manifest 01 <?xml version='1.0' encoding='UTF-8' standalone='yes'?> 我們重點(diǎn)查看紅色部分,這說(shuō)明編譯后的exe程序依賴(lài)于vc90(也即vc2008)的CRT(C運(yùn)行時(shí)庫(kù)),版本9.0.210022.8(這是由于使用/MD選項(xiàng),程序動(dòng)態(tài)的依賴(lài)于CRT,如果使用/MT選項(xiàng),則會(huì)將CRT靜態(tài)鏈接到程序中,當(dāng)然,這會(huì)使程序的尺寸急劇的增長(zhǎng),大概有10倍的大小差距) 當(dāng)exe程序執(zhí)行時(shí),它會(huì)根據(jù)嵌入的manifest文件查找相應(yīng)的依賴(lài)項(xiàng),在這個(gè)HelloWorld.exe程序中,它依賴(lài)于vc90 CRT,因此它會(huì)在“C:\WINDOWS\WinSxS”和“當(dāng)前目錄”下查找相應(yīng)的dll庫(kù)以及manifest文件,(這里指的是xp系統(tǒng),不考慮vista系統(tǒng),具體的參見(jiàn):程序集搜索順序) 在我的機(jī)器上有2個(gè)版本的vc90 CRT(由于安裝了vc2008 express sp1) vc90 CRT的dll庫(kù)位于(9.0.21022.8版本)“C:\WINDOWS\WinSxS\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_d08d0375” 相應(yīng)的manifest文件則位于“C:\WINDOWS\WinSxS\Manifests\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_d08d0375.manifest” vc90 CRT的dll庫(kù)位于(9.0.30729版本)“C:\WINDOWS\WinSxS\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.30729.1_x-ww_6f74963e” 相應(yīng)的manifest文件則位于“C:\WINDOWS\WinSxS\Manifests\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.30729.1_x-ww_6f74963e.manifest” 在這里我們就有一個(gè)疑問(wèn)了,我們的開(kāi)發(fā)環(huán)境是vc2008 express sp1,那么我們的程序鏈接的CRT版本應(yīng)該是9.0.30729版本的啊?(這個(gè)不是我瞎說(shuō)的,大家可以用dependency walker來(lái)查看程序?qū)嶋H鏈接的DLL版本),為什么在manifest文件中依賴(lài)的CRT卻是9.0.21022.8版本的?這里就涉及到一個(gè)新的名詞“policy ",操作系統(tǒng)會(huì)根據(jù)C:\WINDOWS\WinSxS\Policies\x86_policy.9.0.Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_x-ww_b7353f75\9.0.30729.1.policy文件的內(nèi)容,進(jìn)行dll版本的跳轉(zhuǎn)(重點(diǎn)看深藍(lán)斜體字部分)從而選擇了9.0.30729版本的vc90 CRT (這個(gè)所謂的“policy跳轉(zhuǎn)”是道聽(tīng)途說(shuō)來(lái)的,具體的英文資料藏在microsoft的什么地方我就不得而知了。里面夾帶了一些我自己的主觀猜測(cè),不然的話,沒(méi)有辦法解釋manifest版本號(hào)9.0.21022.8是,而實(shí)際鏈接的dll的版本號(hào)卻是9.0.30729) XML語(yǔ)言: 9.0.30729.1.policy 01 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 02 <!-- Copyright (c) Microsoft Corporation. All rights reserved. --> 03 <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 04 <assemblyIdentity type="win32-policy" name="policy.9.0.Microsoft.VC90.CRT" version="9.0.30729.1" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/> 05 <dependency> 06 <dependentAssembly> 07 <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/> 08 <bindingRedirect oldVersion="9.0.20718.0-9.0.21022.8" newVersion="9.0.30729.1"/> 09 <bindingRedirect oldVersion="9.0.30201.0-9.0.30729.1" newVersion="9.0.30729.1"/> 10 </dependentAssembly> 11 </dependency> 12 </assembly>
如果我們將這個(gè)HelloWorld.exe拷貝到其它的機(jī)器上(沒(méi)有安裝vc2008 sp1或Microsoft Visual C++ 2008 SP1 Redistributable Package (x86)),則程序因?yàn)闆](méi)能找到vc90 CRT,而不能運(yùn)行,彈出“應(yīng)用程序配置不正確,程序無(wú)法啟動(dòng)”對(duì)話框。 根據(jù)參考資料的文章中的內(nèi)容,對(duì)于release版程序,有一個(gè)簡(jiǎn)單的辦法就是安裝“vcredist_x86.exe”,文件大小4M左右,自動(dòng)安裝在“C:\WINDOWS\WinSxS”目錄下,包含了CRT、MFC、ATL等庫(kù)的dll和manifest清單文件;整個(gè)安裝時(shí)間不到1分鐘。 如果機(jī)器上安裝了vc2005/vc2008,則會(huì)自動(dòng)的安裝vcredist_x86.exe程序,安裝后在“控制面板”->“添加刪除程序”中有一項(xiàng)“Microsoft Visual c++ 2008 Redistributable - x86 9.0.3.729”(我安裝的是Microsoft Visual C++ 2008 SP1 Redistributable Package (x86) 版本) 注意:要根據(jù)編譯器版本以及vc2005/vc2008是否安裝了sp1補(bǔ)丁進(jìn)行選擇對(duì)應(yīng)的vcredist.exe版本 |
聯(lián)系客服