https://read01.com/Mg337.html (台/湾的论坛,需要f/q)
1、
閱讀此文章的同學先看看我的另外一篇文章:
現在,我們深入探討一下:
《如何使用VS 2013發布一個可以在Windows XP中獨立運行的可執行文件》。
這個問題是比較常見且容易造成初學者困惑的,作為曾經撞了無數次南牆的初級代碼狗終於看到了自己能夠回答的問題,那麼就讓我來簡單闡述一下造成這個問題的簡單原理極其簡單解決方法,如有錯誤紕漏敬請指正。
/*我們討論的是非託管的C++程序。*/
為了方便說明,我們新建一個簡單的控制台應用程式項目,直接如圖:
非常簡單,一個使用了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 。
這個東西的作用就是: