如何分发C运行时(CRT)库

时间:2011-11-11 17:30:43

标签: visual-studio-2008 dependencies

我在Visual C ++ 2008 express上转换VC ++ 6工作区后正在构建一个应用程序。构建本身成功,但我遇到的真正问题是生成的清单,如下所示:

<?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.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>
</assembly>

我的问题是:

如何限制清单仅列出一个版本,最好是9.0.21022.8。以便我可以在我的应用程序中捆绑必要的C-Run时间依赖项?

我知道这个问题可能的根本原因是依赖于某个使用9.0.21022.8的库而我的VC ++ Express 2008可能正在使用9.0.30729.1。这就是为什么两者都被列为依赖。

注意:

我正在遵循http://www.codeproject.com/Tips/211756/How-to-Distribute-C-run-time-CRT-Libraries-with-Yo?display=Print的方法b),该方法讨论了在应用程序文件夹中复制CRT DLL文件和Microsoft.VCXX.CRT.manifest文件。

1 个答案:

答案 0 :(得分:9)

Visual Studio 2008的默认设置是绑定到版本9.0.21022.8。这与您安装的任何版本的Service Pack或修补程序无关,因为对Visual Studio的更新不一定会强制您的应用程序必须升级(如here所述)。

其他可能的版本是Service Pack 1的9.0.30729.1或带有安全更新的SP1的9.0.30729.6161。还有其他人。

由于默认行为,您的应用程序可能正在使用9.0.21022.8,并且有一个库已编译为使用9.0.30729.1。您可以使用以下命令行(described here)找出每个库的哪个版本依赖:

dumpbin /directives <name>.lib

为了使应用程序绑定到的运行时control the version,您可以在项目设置中定义预处理程序符号(必须在项目设置或命令行中)以绑定到默认版本(9.0 .21022.8 - 未定义它们)或绑定到相同版本作为已安装的Visual Studio:

_BIND_TO_CURRENT_VCLIBS_VERSION=1

显然你也可以使用this answer中的定义指定要绑定到的确切版本(也许我应该在输入所有这些之前先找到它)。

如果你发现你的应用程序绑定到9.0.30729.1并且依赖库绑定到9.0.21022.8,那么你只需要删除预处理器定义。

另一个困难是,当您升级Visual Studio时,可再发行文件夹中的运行时合并模块也会升级到这些版本。因此,如果您有一个使用这些合并模块的安装项目,并且您尝试绑定到默认版本,则最终会安装新版本的运行时。

如果您还分发运行时策略合并模块,则解析运行时版本不会成为问题,因为库加载器将在运行时查看运行时的策略并自动加载最新版本,即使绑定到默认版本也是如此。即使私有程序集使用加载程序will first look in the WinSxS folder,因此如果策略存在,您将绑定到最新版本。因此,您的清单中的混合版本号将重定向到最新版本。

有时这不是必需的,您可以控制它以强制它仅加载您指定的清单中的版本,这在this similar SO question的答案中进行了解释。