有的時候,你在
visual c++
上面經過好幾個月的辛勤努力,終於將程式編寫完成並且測試完畢,然而當你試圖在客戶的發布機上執行剛寫好的程式時,有可能會碰到類似下面的錯誤,作業系統告訴你「由於應用程式配置不正確,應用程式未能啟動。重新安裝應用程式可能會糾正這個問題」:
一般情況下,這個問題都是由於程式不能找到所需要的
c執行庫(
crt)而引起的。
在windows xp sp2
以後,windows
引入了side-by-side
執行的概念,這個概念本來是
.net
提出來的,但是
windows
後來將這個概念整合到作業系統層面上來了。大家都應該知道
dll hell
的問題,為了解決
dll hell
的問題,
side-by-side
提出不同版本的
dll檔案可以同時存在於同乙個系統裡面,而且依賴於不同版本
dll的應用程式在執行的時候可以使用到它當初被編譯生成的
dll。前面的話,有點繞,舉個例子:
1.假定你編寫了乙個
c++程式
a,是使用
mfc 8.0
(這個版本是隨著
visual studio 2005
)發布的。
2.之後你的機器公升級了
visual studio
的版本,從
2005
公升級到2008
,2008
的mfc
庫是9.0
版本的,這個時候你的作業系統裡面安裝了兩個版本的
mfc,分別是
8.0和
9.0。
3.你在
visual studio 2008
編寫了另外乙個
c++程式b,
b依賴與
mfc 9.0。4.
如果你執行程式
a的話,作業系統會將
mfc 8.0
載入到a
的程序裡面。
5.如果你這時同時執行程式
b,作業系統會將
mfc 9.0
載入到b
的程序裡面。這就是
side-by-side
的執行概念。
作業系統之所以能夠這樣做,是因為它在引導程式a和
b之前,除了檢視
pe格式裡面a和
b所依賴的
dll資訊,都會檢視a和
b的manifest
檔案。manifest
檔案儲存了
windows
可執行檔案(包括
exe和
dll檔案)要執行起來的環境設定資訊,檔名一般是可執行檔案的檔案全名加上
.manifest
。例如notepad.exe
的manifest
檔案就應該是
notepad.exe.manifest
。例外有的程式將
manifest
檔案直接嵌入到可執行檔案的資源裡面了,這也就是為什麼有的時候你看不到程式的
manifest
檔案的原因。通常來說,乙個
manifest
檔案的內容如下(
test.exe.manifest
檔案):
xmlversion
='1.0' encoding
='utf-8' standalone
='yes'?>
<
assembly
xmlns
='urn:schemas-microsoft-com:asm.v1' manifestversion
='1.0'>
<
trustinfo
xmlns
="urn:schemas-microsoft-com:asm.v3">
<
security
>
<
requestedprivileges
>
<
requestedexecutionlevel
level
='asinvoker' uiaccess
='false'/>
requestedprivileges
>
security
>
trustinfo
>
<
dependency
>
<
dependentassembly
>
<
assemblyidentity
type
='win32' name
='microsoft.vc90.debugcrt' version
='9.0.21022.8'
processorarchitecture
='x86' publickeytoken
='1fc8b3b9a1e18e3b'/>
dependentassembly
>
dependency
>
assembly
>
上面的例子裡面,就說明這個程式依賴於
crt 9.0
,而且是除錯版的,
cpu架構是
32位的
cpu。對於將
manifest
檔案嵌入到資源檔案的程式我們也有辦法看到
manifest
的資訊。
1.一種是使用
mt.exe
(visual studio
自帶的manifest
處理程式):
mt -inputresource:test.exe;#1 /out:test.manifest
2.另外一種是使用
dumpbin
程式將整個
exe的內容列印到乙個檔案,然後用文字編輯器開啟,搜尋
assem
字串樣式就能找到
manifest
資訊:
知道了程式依賴於具體哪乙個
dll以後,你可以將所依賴的
dll拷貝到程式的安裝資料夾裡面,以
crt庫繫結失敗為例,介紹解決步驟:
1.從上例中我們知道程式依賴的
microsoft.vc90.debugcrt
庫,版本號是
9.0.21022.8
,需要32
位機器版本的
crt。這個依賴項一般是因為你的程式是除錯版,所以
visual studio
在編譯的時候,將除錯版的
crt加入程式的依賴項。2.從
visual studio
的安裝資料夾裡面將
d:"program files"microsoft visual studio 9.0"vc"redist"debug_nonredist"x86
中的microsoft.vc90.debugcrt
整個資料夾拷貝到應用程式所在的資料夾裡面,注意:
a)如果你的程式依賴的是
32位的
crt,則要拷貝
x86資料夾裡面的
microsoft.vc90.debugcrt
資料夾,如果是先
x64程式,則要拷貝
x64資料夾裡面。
b)你需要確定
microsoft.vc90.debugcrt
資料夾裡面的
microsoft.vc90.debugcrt.manifest
檔案裡面儲存的版本資訊而你程式依賴的版本資訊匹配,
microsoft.vc90.debugcrt.manifest
裡面的版本資訊大版本號一定要一致,小版本號一定要等於或者大於你程式依賴的
crt的小版本號。比如上例中,我們的程式是依賴於
crt 9.0.21022.8
,而我們的
microsoft.vc90.debugcrt.manifest
的版本是
9.0.30729.1
,這樣是可以的;而
8.0.30729.1
就會有問題。如果大版本號一樣,小版本號不一致的話,乙個比較簡單的方案就是修改程式的
manifest
檔案,使其互相匹配就可以了。
3.如果你的程式不是依賴除錯版本的
crt,而是
release
版本的crt
,直接去微軟
VC編寫的程式不能在其他機器上執行的解決方案
有的時候,你在visual c 上面經過好幾個月的辛勤努力,終於將程式編寫完成並且測試完畢,然而當你試圖在客戶的發布機上執行剛寫好的程式時,有可能會碰到類似下面的錯誤,作業系統告訴你 由於應用程式配置不正確,應用程式未能啟動。重新安裝應用程式可能會糾正這個問題 一般情況下,這個問題都是由於程式不能找...
vs2013編譯的程式在其他機器上執行的環境設定
vs2013編譯的程式在其他沒有安裝vs2013的機器上執行會有問題,網上有很多解決方法,如果你還沒有解決,可以嘗試以下方法,這是我在反覆崩潰,煩躁測試後得到的解決方法。1.安裝vs2013 執行包 vcredist x64.exe 如果這個時候還是不能正常執行,請不要和我一樣崩潰,試試我的解決方法...
關於 C 中 程式在其他裝置上執行 的思考
原來一直頭疼於用 c 11 標準編寫的程式在僅裝有 dev 的電腦上無法執行,因而思考如何讓自己的程式在別人的裝置上執行。進過資料的查詢以及自身的實踐,總結出了以下方法 將除錯的 dubug 改為 release,然後執行程式。結束之後在該項目的資料夾中存在乙個資料夾 release,複製出其中的 ...