[转]如何使用VS 2013發布一個可以在Windows XP中獨立運行的可執行文件
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 。
這個東西的作用就是:
安裝運行使用 VisualStudio2013 生成的 C++ 應用程式時所需的運行時組件。
簡單觀察安裝後系統中多出了哪些文件:
這樣一看,「運行時組件」就變得直觀和具體了。
它們都是什麼呢?我們先去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)和 多線程調試DLL (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】:
事情很簡單,大致就是這樣了。
2、
3、
[转]如何使用VS 2013發布一個可以在Windows XP中獨立運行的可執行文件的更多相关文章
- 【转】如何使用VS 2013发布一个可以在Windows XP中独立运行的可执行文件
问题描述: 用VS2013写好一个程序,在本机上运行一切正常.但是如果直接把exe文件放到另一台机器上用,则会出现: Windows XP:不是一个正常的win32程序 Window 7:缺少msvc ...
- 如何發佈一個完整Node.js Module
本文會透過以下幾個段落,讓各位一步一步學習如何寫一個自已的Node.js Module並且發佈到npm package上 Node.js Module 結構 我們先建立一個 NodeModuleDem ...
- 在windows 2012中安装sharepoint 2013时遇到问题的处理办法
众所周知,sharepoint 2013是早于windows 2012的,所以在安装的时候,总会出现各种奇怪的问题,也就是所谓的一个个坑,为了减少大家掉到坑里的次数和排除故障的时间,我在这里记录下我曾 ...
- (持续更新)vs2012,2013,2015,2017,2019 常用的插件 与 开发中常用的工具
这篇博客 持续更新. 小伙伴们可以复制名称,在vs的扩展和更新中去搜索下载 .其他的工具在官网下载
- 鸟哥的linux私房菜---非常好的linux基础网址【转】
转自:http://linux.vbird.org/linux_basic/0320bash.php 在 Linux 的環境下,如果你不懂 bash 是什麼,那麼其他的東西就不用學了!因為前面幾章我們 ...
- [Java] Thread -- 避免Race Condition (Synchronized)
public class TestRaceCondition implements Runnable{ public static int counter = 0; public static voi ...
- 【转】簡單講講 USB Human Interface Device
原地址http://213style.blogspot.com/2013/09/usb-human-interface-device.html 恩,發本文的原因是看到了以前畢業的朋友在旁邊的對話框問了 ...
- 微软宣布.NET开发环境将开源 支持Mac OS X和Linux
微软宣布.NET开发环境将开源 支持Mac OS X和Linux 投递人 itwriter 发布于 2014-11-13 06:58 评论(55) 有4388人阅读 原文链接 [收藏] « » ...
- VMware虛擬化技術實作問答
http://www.netadmin.com.tw/article_content.aspx?sn=1202130002&ns=1203280001&jump=3 Q4:啟用VMwa ...
随机推荐
- Redis集群管理(二)
1.进入集群客户端 任意选一个redis节点,进入redis 所在目录 cd /redis 所在目录/src/ ./redis-cli -h 本地节点的ip -p redis的端口号 -a 密码 [r ...
- SQL Server经典函数之数字去零
需求: 针对带有小数点的数字信息,去除小数点后多余的零 可能存在的情况: 1.精度范围内,出现多余的零 eg:1234.3400 想要的结果为1234.34 2.精度变大出现的多余的零, ...
- redhat 6安装详解
备注:redhat 6 系列OS安装步骤一致. 此处安装redhat 6.5 64位版本,即rhel-server-6.5-x86_64-dvd.iso 一.安装RHEL 6.5 用光盘成功引导系统, ...
- thinkphp中 volist循环的 mod取值的问题
<ul> <volist name="data" id="arr" key="k" mod="2"&g ...
- Elasticsearch之settings和mappings(图文详解)
Elasticsearch之settings和mappings的意义 简单的说,就是 settings是修改分片和副本数的. mappings是修改字段和类型的. 记住,可以用url方式来操作它们,也 ...
- PostgreSQL数据库的安装与PostGIS的安装(转)
原文:http://lovewinner.iteye.com/blog/1490915 安装postgresql sudo apt-get install postgresql-9.1 postgre ...
- kubernetes实战(三):k8s v1.11.1 持久化EFK安装
1.镜像下载 所有节点下载镜像 docker pull kibana: docker tag kibana: docker.elastic.co/kibana/kibana: docker pull ...
- Nginx 使用总结
一.使用 nginx 实现 灰度发布 灰度发布,现在是很多大项目的一个标配运维特性,我们可以将一个“新的版本代码”发布到集群中的少数几台(组)机器上,以便引入线上少量真实用 户进行测试,用于验证产品改 ...
- 'ascii' codec can't decode byte 0xc4 in position 27: ordinal not in range(128)
This error happens when I try to run d:\linux\linuxkernel\android\内核\blog\BlogBackup(v1.1)source\htm ...
- ScyllaDB - 基础部署
基础环境 操作系统: CentOS 7.2: 集群节点(虚拟机):172.16.134.15 ~ 17: 基础准备 安装依赖和卸载 abrt ( abrt 和 coredump 配置冲突 ): sud ...