VC2008发布程序时指定库版本

   用vc2008动态编译(/MD,/MDd)的程序,在进行发布或者部署时,经常会因为目标机器上没有相应的dll库版本而引发“应用程序配置不正确,程序无法启动”问题。而解决方法也不是将vc安装目录下对应的dll库拷贝到程序路径下这么简单,其中涉及到的一些细节还是够大家研究一番的。

   首先我们需要很清楚地了解side-by-side、manifest文件等这些概念,可以参考我博客的文章 详解“由于应用程序配置不正确,应用程序未能启动”

   知道问题产生的原由,我们就明确了解决vc2008程序发布问题的目标:将程序真正链接的dll库文件和程序一起打包,并保证程序的manifest配置能够正确链接到这些库。如果你的vc2008是没有打过补丁的原始版本,那么解决起来还是比较简单的。此时CRT/MFC/ATL库的版本号为9.0.21022.8,我们直接将vc安装目录下\VC\redist\x86\下的Microsoft.VC90.CRT和Microsoft.VC90.MFC两个文件夹及其文件拷贝到分发程序的运行路径下就可以了。如果做安装包的话,将这两个文件夹与应用程序一起打包安装,就可以使程序运行于目标机器上了。

   如果是打了sp1补丁或者sp1atl安全更新补丁的vc2008,解决起来就比较麻烦了,因为你的CRT/MFC/ATL等库版本已经被更新到了9.0.30729.1和9.0.30729.4148(去C:\WINDOWS\WinSxS路径下查看,另外vc2008安装目录下的redist包已经被替换为最新的版本)。你也许会说,库版本被更新了,那么编译出来的程序manifest中指向的链接库版本也应该是最新的,\VC\redist\x86\下的Microsoft.VC90.CRT和Microsoft.VC90.MFC两个文件夹中的库文件也是最新的,那么我们也将这两个文件夹和应用程序一起打包发布不就可以了吗?理论上应该是这样,而且也不应该有不是这样的理由,但是世界上的事情就是这样,总会出现意外,而且等你弄明白了来龙去脉,你还不能对这次意外说些什么。

   比如我们编译一个test.exe程序,那么打开编译输出文件夹中的test.exe.intermediate.manifest文件,或者直接用UltraEdit打开exe文件,你会发现指向的链接库版本竟然是9.0.21022.8。(注意,可以通过工程属性-> Manifest Tool -> Input and Output-> EmbedManifest项设置是否将manifest信息嵌入exe中,一般应该选择“Yes”。)如下面两张图所示。

 

VC2008发布程序时指定库版本



VC2008发布程序时指定库版本

   难道vc2008并没有链接最新版本的runtime库?用DependencyWalker查看一下test.ext实际链接的DLL版本,发现还是最新的9.0.30729.4148版。

 

VC2008发布程序时指定库版本

   这是怎么回事呢?vc2008生成的manifest清单信息竟然是错误的!对于这个问题,有人认为是vc的bug,但是微软似乎也给出了相应的解释。在重新分发应用程序并将其绑定到特定库这篇文章中,微软指出“在编译应用程序时,它会绑定到可用库的原始发行版。即使您的计算机上安装了更高的发行版本,也是如此。例如,如果您的计算机上安装了Visual C++ 2008 SP1,则在此计算机上编译的任何应用程序都仍将依赖 Visual C++ 2008的原始发行版。”这样做的原因是“借助默认绑定行为,可以在获取新发行版之后重新编译您的程序,还可以分发新的可执行文件。已安装所需库的最终用户将只需要新的可执行文件;您不必打包和重新安装最新的库。”也就是说,微软在生成manifest信息的时候加了一个策略,用户在编译程序时,可以选择将程序绑定到RTM版本(原始版本)的运行时,或者当前版本(最新版本)的运行时;选择前者意味着用户分发程序以后,如果更新了运行库版本,需要更新分发出去的程序时,只要在新环境下编译更新程序,然后分发程序本身就可以了,不用同时更新运行库文件(当然如果新程序中依赖新版运行库中的新功能除外),因为此时的manifest信息还是指向原来的版本;如果选择后者,没什么好说的,必须同时更新程序和库。在默认情况下,微软应用前者。这就是为什么我们看到test.exe中的manifest信息和实际链接库的版本会不一样。

   至于具体每个版本对应的策略,大家可以自己去C:\WINDOWS\WinSxS\Policies\下打开相应的.policy文件查看。明白了问题产生的实质,我们就自然有了解决办法,那就是选择“按最新版本”生成程序。在你的代码中(可以选择在stdafx.h文件中),加入以下代码指定CRT和MFC库使用最新版本(实际上是指定manifest信息):

   #define _BIND_TO_CURRENT_CRT_VERSION 1
    #define_BIND_TO_CURRENT_MFC_VERSION 1

   当然,根据需要还可以指定ATL和OPENMP库:

   #define _BIND_TO_CURRENT_ATL_VERSION 1
    #define_BIND_TO_CURRENT_OPENMP_VERSION 1

   或者可以简单地加入

   #define _BIND_TO_CURRENT_VCLIBS_VERSION 1
   指定以上所有库都用最新版本。

   这个方法可以很方便地解决问题,不过我们还有更简单的办法。仔细分析一下前面的分析,会发现其实问题的原因在于程序中manifest信息指向的版本和实际链接的版本对不上号。我们可以用记事本修改“Microsoft.VC90.CRT”和“Microsoft.VC90.MFC”等文件夹下的“Microsoft.VC90.CRT.manifest”和“Microsoft.VC90.MFC.manifest”等文件,将其中的版本号改为“9.0.21022.8”,这样就跟程序中的manifest信息一致了,当然我们的dll库版本应该是实际链接的“9.0.30729.4148”,只是用这个小技巧欺骗一下系统。这样,我们只需要打包绑定到最新版运行库的应用程序、\VC\redist\x86\下的Microsoft.VC90.CRT和Microsoft.VC90.MFC两个文件夹就可以了,只不过此时两个文件夹下“Microsoft.VC90.CRT.manifest”和“Microsoft.VC90.MFC.manifest”文件中的版本号被改成了“9.0.21022.8”。

 

   到此为止,我们终于将vc2008下发布应用程序的问题搞清楚了。幸运的是,在vs2010中我们不用再面对这个问题,而且windowsvista和windows 7系统都自带了最新版的运行库,这个问题也许即将成为历史。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: VC90动态是指使用Visual C++ 2008编译器生成的动态链接。VC90代表Visual C++ 2008,是该编译器的版本号。动态链接是一种在程序运行加载的文件,它在多个程序之间共享代码和资源,可以提高程序的模块化和复用性。 在Visual C++ 2008中,VC90动态有很多种类,如MFC、ATL等。MFC(Microsoft Foundation Class)是一组C++类,用于开发Windows应用程序。它提供了丰富的图形界面、窗口管理、事件处理等功能,大大简化了Windows应用程序的开发过程。ATL(Active Template Library)是一组C++模板类,用于开发COM组件。它提供了通用的COM接口和对象模型,方便了COM组件的开发和使用。 通过使用VC90动态,我们可以充分利用已有的代码和资源,加快开发速度,提高程序的稳定性和可扩展性。在编译和链接,我们需要将使用到的动态加入到工程中,并在代码中引用相应的头文件和函数,以便使用其中的功能。 在使用VC90动态,需要注意以下几点。首先,要确保编译器版本与动态版本相匹配,否则可能会出现兼容性问题。其次,要正确设置工程的和包含目录,以便编译器能够找到相关的文件和头文件。另外,要注意动态的部署和打包,确保目标系统中存在所需的文件,并设置正确的路径。 综上所述,VC90动态是Visual C++ 2008编译器生成的动态链接,通过使用这些动态,我们可以方便地开发Windows应用程序和COM组件,提高开发效率和程序质量。但在使用需要注意编译器版本和头文件的设置,以及动态的部署和打包,以确保程序的正确运行。 ### 回答2: VC90动态是指Microsoft Visual C++ 2008(简称VC 2008)生成的一系列动态链接(DLL)文件,用于在使用VC 2008编写的程序中引用和调用中的函数和资源。 在VC 2008中,VC90动态主要由多个DLL文件组成,其中最常见的是msvcr90.dll和msvcp90.dll。msvcr90.dll包含了C运行(CRT)的函数和资源,用于支持C语言程序的运行;msvcp90.dll则包含了C++标准的函数和资源,用于支持C++程序的运行。 使用VC90动态需要在程序编译和链接阶段正确配置和引用相关文件。在项目属性设置中,需要指定正确的文件目录和文件名称,以便编译器能够找到并链接相应的。在代码中,需要包含相关的头文件,并在使用中函数和资源进行正确的命名空间和函数调用。 VC90动态的使用可以帮助开发者充分利用已经实现的功能模块,减少代码重复,提高程序开发效率。同,由于VC90动态是在编译期间链接,而不是静态编译到可执行文件中,因此可以通过更新或替换文件的方式,方便地升级和维护程序。 总之,VC90动态是VC 2008中用于提供函数和资源的一组文件,使用它可以方便地开发和维护VC 2008程序。 ### 回答3: VC90动态是指使用Microsoft Visual C++ 2008编译器生成的动态链接。VC90是指Visual C++ 2008,是一个在2008年发布的集成开发环境(IDE)和编译器套件。该版本的Visual C++支持使用C++语言进行软件开发,并且可以生成可执行文件以及动态链接等形式的程序。 在VC90动态中,通常会包含一些常用的函数、类、变量以及特定功能的实现。这些动态链接可以被其他应用程序调用和使用,从而可以避免不同应用程序中重复编写相同的功能代码。通过使用动态,我们可以提高开发效率,减少代码冗余,同也便于维护和更新。 VC90动态是使用Visual C++ 2008编译器编译生成的,所以在使用需要保证对应版本的运行被正确安装。运行是一些在程序运行需要的动态链接,它们提供了一些常用的函数和资源,以便程序能够正确执行。因此,如果要在一台计算机上运行VC90动态生成的程序,需要安装相应的Visual C++ 2008运行。 总之,VC90动态是一种使用Visual C++ 2008编译器生成的动态链接,它可以被其他应用程序调用和使用,提供了一些常用的函数和功能实现。在使用需要保证对应版本的运行被正确安装。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值