VS2008程序部署终极解决方法

chzuping 2014-10-06 07:41:55
此文来源于我的个人网站,在这里编辑图片感觉非常吃力,有兴趣阅读图文完整版请移步到这里

缘起,本文也是在参考其他网文的基础上加上自己的实际操作验证完成的,应用程序配置不正确这个问题让人非常之头疼加上觉得他们写得不够详细,但是可能会有的读者不能正确操作而放弃,所有有了此文。

VC2005以上环境下编译好的可执行程序发布时,在未配置VC2008或VC2005的环境下运行.经常有"应用程序配置不正确,程序无法启动"这样的问题.

解决这类问题常用方法就是采用MT过MTd选项静态链接运行库,其实就是将运行库静态编译到exe中或者安装redist包。这种方法有许多弊端:

1.exe的体积会大不少。

2.exe如果调用第三方dll或静态库,编译时候也必须采用MT过MTd选项。不然会编译不过,调用的第三方DLL会出现各种各样的内存问题。

3.安装redist包有点麻烦,还有可能遇到版本问题,比如VS2008和VS2008SP1要分别安装。

下面介绍怎么在使用MD或者MDd选项(在此我们只讨论release版本,debug版本一般不用于发布,操作也是一样的)时把需要的运行库随exe一起部署的终极解决方法。

第一步:将嵌入清单选择为否,然后编译,会在exe所在的Release目录生成程序名+exe.manifest文件。
第二步:将第一步所生成的程序名+exe.manifest文件打开,删除其中的publicKeyToken,Microsoft.Windows.Common-Controls对应项不要删,我的VS2008删除后如下所示:
<?xml version='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.CRT' version='9.0.21022.8' processorArchitecture='x86'/>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.VC90.MFC' version='9.0.21022.8' processorArchitecture='x86'/>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*' />
</dependentAssembly>
</dependency>
</assembly>
第三步:将VS2008发布目录下(如果VS安装在D盘的话,为D:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86,其他类推)的manifest包含的运行库拷贝到exe所在的Release目录(本例子需要拷贝的目录为Microsoft.VC90.CRT和Microsoft.VC90.MFC)。





第四步:至此我们的发布目录包含的文件和件夹如下,接下来解决版本问题(这一步非常关键,参考文章讲得有点模糊),其实很简单,用文本编辑器打开Microsoft.VC90.CRT和Microsoft.VC90.MFC文件夹中的Microsoft.VC90.CRT.manifest和Microsoft.VC90.MFC.manifest两个文件,首先删除这两个文件中的publicKeyToken,然后将其中version字段改成和程序名+exe.manifest对应version字段一样。如本例子Microsoft.VC90.CRT.manifest的version字段需要改成9.0.21022.8,Microsoft.VC90.MFC.manifest的version字段也需要改成9.0.21022.8。



第五步:至此我们的程序已经可以发布了(把Release目录下的文件打包发布即可),如果您嫌麻烦可以不用往下看了。其实我们可以把程序名+exe.manifest这个文件嵌入到exe里面去,这个样发布程序时就少了一个看着碍眼的清单文件。为了使用外部清单文件,首先必须把生成清单文件关闭,如下图所示:



第六步:接下来我们把Release目录生成程序名+exe.manifest嵌入到exe中去,如下图所示,注意我们又把嵌入清单改回来了。



第7步:重新编译,在输出里面得知清单文件嵌入到exe里面去了如下。至此我们发布程序时已经可以不要Release目录生成程序名+exe.manifest这个文件。

1>------ 已启动生成: 项目: TestManifest, 配置: Release Win32 ------

1>正在链接...

1>正在生成代码

1>已完成代码的生成

1>正在嵌入清单...

第8步:到此结束,什么?还有人怀疑程序运行后是不是调用exe目录下Microsoft.VC90.CRT.manifest和Microsoft.VC90.MFC.manifest中的运行库(因为暂时找不到一个干净的系统测试)。我们可以这样做,运行exe后,把exe目录下Microsoft.VC90.CRT.manifest和Microsoft.VC90.MFC.manifest中的dll文件改名,或删除(最好拿msvcr90.dll开刀,其他的可能exe不会调用到),如果被调用,是无法改名和删除的。

第9步:如实确实删不掉或者无法改名,证明dll确实被调用了。但是还有较真的或强迫症患者(出门老是怕忘记锁门),那就只有拷贝到一个干净的系统测试了,还有一招就是用Unlocker查询dll被哪个exe占用,入下图:


至此本文结束,下面附上参考资料:

http://blog.kalmbach-software.de/2008/05/03/howto-deploy-vc2008-apps-without-installing-vcredist_x86exe/
http://blog.163.com/smart_84@126/blog/static/6657573520104251007316/


...全文
295 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
shen_wei 2014-10-08
  • 打赏
  • 举报
回复
不错,不过现在都用打包工具了!!
dvlinker 2014-10-07
  • 打赏
  • 举报
回复
顶一个!顶一个!

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧