C++ 应用程序不与VS 2008 SP1 DLL一起运行,以前的版本可与RTM版本一起运行
自从我们从Visual Studio 6切换到Visual Studio 2008以来,我们一直在使用MFC90.dll和msvc[pr]90.dll以及私有并排配置中的清单文件,以便不必担心版本或将它们安装到系统中 在SP1之前,它运行良好(在我们的开发人员机器上仍然运行良好)。既然我们已经做了一些SP1后的测试,我从昨天早上就开始紧张了 首先,我们的NSIS安装程序脚本从redist文件夹中提取DLL和清单文件。这些都不再正确,因为应用程序仍然链接到RTM版本 因此,我将define forC++ 应用程序不与VS 2008 SP1 DLL一起运行,以前的版本可与RTM版本一起运行,c++,visual-studio-2008,mfc,C++,Visual Studio 2008,Mfc,自从我们从Visual Studio 6切换到Visual Studio 2008以来,我们一直在使用MFC90.dll和msvc[pr]90.dll以及私有并排配置中的清单文件,以便不必担心版本或将它们安装到系统中 在SP1之前,它运行良好(在我们的开发人员机器上仍然运行良好)。既然我们已经做了一些SP1后的测试,我从昨天早上就开始紧张了 首先,我们的NSIS安装程序脚本从redist文件夹中提取DLL和清单文件。这些都不再正确,因为应用程序仍然链接到RTM版本 因此,我将define for
\u BIND\u TO\u CURRENT\u VCLIBS\u VERSION=1
添加到我们的所有项目中,以便它们将使用redist文件夹中的SP1 DLL(或新service Pack推出后的后续DLL)。我花了几个小时才找到这个
我仔细检查了编译过程中中间文件文件夹中生成的清单文件,它们正确地列出了9.0.30729.1 SP1版本。我已经检查了两次和三次,这取决于一台干净的机器:它所有链接到本地DLL都没有错误
运行应用程序仍会出现以下错误:
应用程序未能正确初始化(0xc0150002)。单击“确定”终止应用程序
我在谷歌或微软上所做的搜索都没有找到任何与我的具体问题相关的内容(但有一些回溯到2005年的错误消息)
有人对SP1有过类似的问题吗
选项:- 找到问题并修复,使其正常工作(首选)
- 安装redist
- 找出旧的RTM DLL和清单文件,删除#define以使用当前文件。(我在早期的安装版本中安装了它们,因为Microsoft将它们从您的redist文件夹中炸出!)
编辑:我下载了vcredit_x86.exe,并在我的测试机器上运行了VS2008SP1。它起作用了。使用SP1 DLL。和我的RTM链接应用程序。但不是在一个私下并列的分布,在SPP1之前工作。 < P>我上个星期已经亲自解决了这个问题,认为我自己现在是个专家了。p> 我99%确信并非所有DLL和静态库都是用SP1版本重新编译的。你需要把
#define _BIND_TO_CURRENT_MFC_VERSION 1
#define _BIND_TO_CURRENT_CRT_VERSION 1
你正在使用的每一个项目。对于每个实际大小的项目,很容易忘记一些没有重新编译的小库
有更多的标志定义绑定到哪个版本;它被记录在。作为上述行的替代,您还可以
#define _BIND_TO_CURRENT_VCLIBS_VERSION 1
它将绑定到所有VC库的最新版本(CRT、MFC、ATL、OpenMP)
然后,检查嵌入的清单上的内容。下载XM资源编辑器:。打开解决方案中的每个dll和exe。在“XP主题清单”下查看。检查右侧的“版本”属性是否为“9.0.30729.1”。如果是“9.0.21022”,则某些静态库正在为旧版本引入清单
我发现在很多情况下,这两个版本都包含在清单中。这意味着一些库使用sp1版本,而其他库则不使用
调试哪些库没有设置预处理器指令的一个好方法是:临时修改平台头,以便在编译尝试嵌入旧清单时停止编译。打开C:\Program Files\Microsoft Visual Studio 9.0\VC\crt\include\crtassem.h。搜索“21022”字符串。在该定义中,放置无效的内容(将“define”更改为“blehbleh”左右)。这样,当您在编译一个未设置\u BIND\u TO\u CURRENT\u CRT\u VERSION
预处理器标志的项目时,您的编译将停止,您将知道您需要添加它们或确保它应用于所有地方
另外,请确保使用Dependency Walker,这样您就知道要引入哪些DLL。在虚拟机上安装新的Windows XP副本最简单,无需更新(仅SP2)。通过这种方式,您可以确定SxS文件夹中没有正在使用的东西,而不是您提供的并排DLL。我刚刚想起了另一个发现哪些静态库出现问题的技巧:通过字符串“21022”的静态库执行“grep”。但是,不要使用wingrep之类的“普通”grep工具,因为它们不会显示这些字符串(它们认为这是一个二进制文件,并查找原始的非unicode字符串)。使用资源工具包中的“strings”实用程序(我想现在在Russinovich网站上)。那个可以通过二进制文件进行grep。因此,让这个“字符串”遍历整个源代码树,您将看到二进制文件(DLL和静态库),其中包含对错误清单(或其中包含错误版本的清单)的引用。对于第三个选项,您可能可以在dev机器上的C:\WINDOWS\WinSxS目录中找到9.0.21022版本的DLL和清单。如果可以,您可以设置自己的redist目录,并在应用程序中安装这些文件 或者,您可以使用Visual Studio提供的9.0.30729.1版本,并伪造随应用程序安装的清单,以报告它提供的是9.0.21022 DLL,而不是9.0.30729.1。运行时链接器似乎并不介意。有关更多信息,请参阅这篇文章,它对解决这些问题非常有帮助 这两种解决方法都修复了我在使用VS2008 Expr将DLL部署为专用程序集时遇到的问题
Situation | .exe (A) | embedded manifest (B) | VC DLLs (C) | VC manifests (D)
-----------------------------------------------------------------------------
1 | v2 | v1 | v1 | v1
2 | v2 | v1 | v2 | v2
3 | v2 | v1 | v2 | v1
4 | v2 | v2 | v2 | v2