【轉】如何使用VS 2013發布一個可以在Windows XP中獨立啟動並執行可執行檔

來源:互聯網
上載者:User

標籤:連結   windows   技術分享   四種   檔案中   實驗   控制台   結構   systemv   

問題描述:

用VS2013寫好一個程式,在本機上運行一切正常。但是如果直接把exe檔案放到另一台機器上用,則會出現:

Windows XP:不是一個正常的win32程式

Window 7:缺少msvcp120.dll

能否有一種方法,把程式運行所需要的環境一併打包,使之可以在任何Windows電腦上使用?

 

 

為了方便說明,我們建立一個簡單的控制台應用項目,直接

 

非常簡單,一個使用了C++標準庫的控制台應用程式,在裝有開發環境的本機順序執行出如下效果:

真實一個曠世奇作,我們迫不及待地就此發給XP老哥炫耀,萬萬沒想到:

 

裝逼不成反被XP老哥奚落:“負分滾粗!”

這裡我們遇到了題目遇到的問題之一,確實叫人納悶,不過隨便搜尋一下就會有解決方案:

 

是的,在項目配置屬性中,將平台工具選擇為“Visual Studio 2013 -Windows XP(v120_xp)”,即可解決“無效的Win32應用程式”問題。

 

但是我們還要知其然所以然,為什嗎?

項目預設的Visual Studio 2013(v120) 與 Visual Studio 2013 - Windows XP(v120_xp) 產生出來的可執行檔有何區別,以至於前者在XP上執行會出現那樣的錯誤?

最直覺的方法自然是比較一下兩版本執行檔案的區別,我們選用PE(Portable Executable :32位或64位Windows作業系統使用的可執行程式或者動態連結程式庫的檔案格式)工具 Stud_PE 進行PE檔案頭結構比較,很容易看出區別:

 

看到打紅叉的地方,就是兩個檔案不同之處,其它地方几乎沒有區別。

關於PE檔案結構是另外一個話題,我們暫不深入討論。

單就這兩處我們顧名思義一下就很容易明白:

MajorOSVersion,(目標)作業系統主要版本號 ,選擇預設平台工具集的檔案的值是6,後者是5。

MinorOSVersion ,(目標)作業系統次版本號碼,前者是0,後者是1。

MajorSubsystemVersion,(目標)Win32子系統主要版本號,前者是6,後者是5。

MinorSubsystemVersion,(目標)Win32子系統次版本號碼,前者是0,後者是1。

 

總結一下:一個是6.0,一個是5.1。

很明顯5.1不就是XP的版本號碼麼,6.0就是Vista唄?

我們是否可以認為,項目預設選擇的“平台工具集”產生的可執行檔是不能在6.0以下版本的Windows啟動並執行?

 

實驗結果是:當我把6.0手動修改成5.1之後,這個檔案立刻可以在XP裡運行了,事實上,Major/MinorOSVersion的值似乎沒有起到什麼作用,僅僅修改XxxxxSubsystemVersion的值就可以保證程式順利執行起來了。反之亦然。同時還發現:在XP中,改為5.1可以,5.2及更高就不行。

 

對於這個問題的認識雖然仍流於表面,但由於知識有限,我們就不再探究PE結構中的這幾個值的深層次含義了。當然如有大牛指點一二就更好了。

 

現在好了!我們不但解決了XP的運行問題,還大致瞭解了問題的根源。那麼讓我們繼續發布吧!

 

將新的、XP的、“5.1的”版本發給XP老哥:

 

我勒個去?你等等,我再編譯一個release版本......試試:

 

擦?不是說好的“Release”嗎?你等等,不就是一個dll檔案嗎,我這裡有!我發給你......

我從自己的系統(Win 8.1 x64)C:\Wdinwos\system32 檔案夾找一個MSVCP120.DLL發過去:

是啊,這不是逗呢?拿64位的dll檔案去冒充32位的,能行?重新去VS目錄扒一個正確的32位msvcp120.dll補上:

 

又來,這次叫做MSVCR120.dll ,不仔細看還真沒認出來。繼續補上:

呵呵呵呵呵,終於得以正確運行了,但是這麼狼狽的炫耀怎麼能讓人高興起來呢?

 

經過一番折騰,好歹知道了是因為缺少檔案,那麼下次發布程式把這些瓶瓶罐罐DDLL都帶上打包不就行了嗎?沒錯,確實是這麼個道理,但總感覺很不專業的樣子。

所以,一個正常的解決方案就是和其它答案中所說的那樣,讓目標機器安裝VisualC++Redistributable Packages forVisualStudio2013

 

這個東西的作用就是:

安裝運行使用 VisualStudio2013 產生的 C++ 應用程式時所需的運行時組件。

簡單觀察安裝後XP系統中多出了哪些檔案:

 

這樣一看,“運行時組件”就變得直觀和具體了。

它們都是什麼呢?我們先去我們電腦VS的安裝目錄中看一下:

 

通過路徑很容易理解,這是有關VC的redist(再發行)的東西,我們進x86看一下:

有關CRT(執行階段程式庫),MFC,MFCLOC(MFC的本地化檔案)等等,我們看看CRT裡面:

 

看到了眼熟的這兩個dll了。實際上,你參考前面那個XP多出檔案的圖片,那些dll都能在這裡找到。

這就是Visual C++ Redistributable 包括的東西,每個VS版本都不一樣。VS2013對應的就是120

 

那管它是VS2013還是2012還是2008,對應的發行包給裝上不就完了。

沒錯。但是我們還要繼續研究一下,至少,研究一下如何讓一個可執行檔“獨立”運行在XP上。

 

回到項目配置,如:

 

我們看到,運行庫這一項,包含4中選擇。

發話不多說,我們簡單粗暴乾脆每一種都產生一個進行比較:

 

四種版本,分別起了對應的名稱,多線程(MT)多線程DLL(MD)多線程調試(MTd),多線程調試DLL(MDd)

利用Stud_PE 觀察比較它們的函數匯入表,發現:

1、多線程DLL(MD)和多線程調試(MDd)

兩者都匯入了2個MSVCxxxx.dll(黃箭頭所指),但細看又不同,調試版本(MDd)匯入的是MSVCP120D.dll和MSVCR120D.dll,比非調試(MD)的那個都多一個字母‘D‘。很明顯這是配套給調試版的執行階段程式庫。而我們之前安裝的發行包所部署的都是不帶D的版本,是給Release版的程式配套使用的。

順便一提MSVCP代表MicroSoft Visual C++(Plus) ,MSVCR則代表MicroSoft Visual C(沒有+)Runtime。 一個是C++執行階段程式庫一個是C執行階段程式庫

 

2、多線程(MT)與 多線程調試(MTd)

兩者貌似一樣,都沒有MSVCP和MSVCR函數匯入,只有Kernel32.dll。同時觀察這兩個檔案的體積,都比MD或MDd大了很多,這正式它們不需要匯入執行階段程式庫DLL函數的原因,因為它們把執行階段程式庫靜態編譯到自己的檔案中去了。這也代表著它們啟動並執行時候不會再依賴外部的執行階段程式庫DLL檔案。

 

所以,想要你的exe獨立運行在XP中:

1、將平台工具集選擇為"Visual Studio 2013 - Windows XP (v120_xp)"。

2、將運行庫選擇為 【多線程 /MT 】或【多線程調試 /MTd】。

3、當然如果使用了MFC,同理的要設定【在靜態庫中使用MFC】:

 

 

轉自《如何用 VS 2013 打包 VC++ 程式?》 Dr Yao的回答。

 

以上。

 

【轉】如何使用VS 2013發布一個可以在Windows XP中獨立啟動並執行可執行檔

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.