关于vs2008 sp1 C++ 生成的 manifest 中运行库版本号的问题

一次偶然的发现vs2008 sp1生成manifest文件中vc++ runtime的版本号为9.0.21022.8,而sp1的vc++ runtime的版本应该是9.0.30729.1。
google了一下,发现有人说这是vs2008 sp1的bug,并提交到ms的feedback:VC9 SP1 generates manifests with the wrong version number
然而今天查看了msdn,事实上这并不是一个bug。MSDN:重新分发应用程序并将其绑定到特定库

其中默认绑定行为有下面描述

本节介绍用 Visual C++ 2008 和更高发行版编译的应用程序的默认行为。在编译应用程序时,它会绑定到可用库的原始发行版。即使您的计算机上安装了更高的发行版本,也是如此。例如,如果您的计算机上安装了 Visual C++ 2008 SP1,则在此计算机上编译的任何应用程序都仍将依赖 Visual C++ 2008 的原始发行版。

并附带一个说明

如果您的应用程序依赖最新发行版中引入的功能,则必须分发并重新安装新库,否则应用程序将无法运行。

由此可以发现vs2008 sp1生成的manifest并不是错误的,而且从process explorer中查看应用程序调用的vc++ runtime的版本号你会发现实际上调用的是9.0.30729.1。至于原理请参考MSDN:Visual C++ Libraries as Shared Side-by-Side Assemblies
如果你想强制manifest中vc++ runtime为9.0.30729.1
可以使用下面的代码

如果希望强制应用程序要求在计算机上安装最新的库,请使用下面的一行或多行代码:
#define _BIND_TO_CURRENT_CRT_VERSION 1;
#define _BIND_TO_CURRENT_ATL_VERSION 1;
#define _BIND_TO_CURRENT_MFC_VERSION 1;
#define _BIND_TO_CURRENT_OPENMP_VERSION 1;
借助下面的代码行,可以将应用程序绑定到所有 Visual C++ 库的当前版本。此代码行的效果是上面所有代码行的效果之和。
#define _BIND_TO_CURRENT_VCLIBS_VERSION 1;
说明:
建议您在命令行级别定义这些宏。如果您更愿意在代码中包括这些定义,则必须将它们放在每个编译单元的最前面,例如 stdafx.h 中的前几行。
如果将应用程序绑定到一组库,则在装有这些库的早期版本的计算机上,应用程序将无法运行。如果将应用程序绑定到由最少库组成的特定版本,则建议您随应用程序一起提供所需版本的库。

不过有一个弊端,如果使用了vs2008编译的不带相关宏的静态库,这时manifest中会出现下面这种情况。只有定义相关的宏重新编译所用到的lib才会只有第一个Microsoft.VC90.CRT的描述。

  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.VC90.CRT' version='9.0.30729.1' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.VC90.CRT' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </dependency>
此条目发表在分类目录。将固定链接加入收藏夹。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据