【转】如何使用VS 2013发布一个可以在Windows XP中独立运行的可执行文件

时间:2022-03-25 05:07:33

用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 ,不仔细看还真没认出来。继续补上:

呵呵呵呵呵,终于得以正确运行了,但是这么狼狈的炫耀怎么能让人高兴起来呢?