应用程序不能与 VS 2008 SP1 DLL 一起运行,以前的版本适用于 RTM 版本

2022-01-05 00:00:00 visual-studio-2008 c++ mfc

自从我们从 Visual Studio 6 切换到 Visual Studio 2008 以来,我们一直在使用 MFC90.dll 和 msvc[pr]90.dll 以及私有并行配置中的清单文件,以免担心版本或将它们安装到系统中.

SP1 之前,这运行良好(并且在我们的开发人员机器上仍然运行良好).现在我们已经在 SP1 之后做了一些测试,我从昨天早上开始就一直在拔头发.

首先,我们的 NSIS 安装程序脚本从 redist 文件夹中提取 dll 和清单文件.这些不再正确,因为该应用仍链接到 RTM 版本.

所以我将 _BIND_TO_CURRENT_VCLIBS_VERSION=1 的定义添加到我们所有的项目中,以便他们将使用 redist 文件夹中的 SP1 DLL(或随着新服务包的出现而使用后续的).我花了几个小时才找到这个.

我已经仔细检查了编译的中间文件文件夹中生成的清单文件,它们正确地列出了 9.0.30729.1 SP1 版本.我已经两次和三次检查取决于一台干净的机器:它所有链接到本地?? dll 都没有错误.

运行应用程序仍然出现以下错误:

<块引用><块引用>

应用程序未能正确初始化 (0xc0150002).单击确定"终止应用程序.

我在 google 或 microsoft 上进行的所有搜索都没有提出与我的具体问题相关的任何内容(但此错误消息可以追溯到 2005 年).

有人在使用 SP1 时遇到过类似的问题吗?

选项:

  • 找到问题并修复它,使其正常工作(首选)
  • 安装redist
  • 挖掘旧的 RTM dll 和清单文件并删除 #define 以使用当前的.(我在较早的安装程序版本中安装了它们,因为 Microsoft 将它们从您的 redist 文件夹中删除!)

我已经尝试在关闭定义的情况下重新构建(链接到 RTM dll),只要 RTM dll 安装在文件夹中,它就可以工作.如果插入 SP1 dll,则会出现以下错误:

<块引用>

c:Program Files......X.exe

此应用程序无法启动,因为应用程序配置不正确.重新安装应用程序可能会解决此问题.

没有其他人需要处理这个问题吗?

只是为了咧嘴笑,我在我的测试机器上下载并运行了 VS2008SP1 的 vcredist_x86.exe.有效.使用 SP1 DLL.还有我的 RTM 链接应用程序.但不能在 SP1 之前运行的私有并行发行版中.

解决方案

我上周亲自解决了这个问题,现在认为自己有点专家级了 ;)

我 99% 确定并非所有 dll 和静态库都使用 SP1 版本重新编译.你需要把

#define _BIND_TO_CURRENT_MFC_VERSION 1#define _BIND_TO_CURRENT_CRT_VERSION 1

进入您正在使用的每个项目.对于每个实际大小的项目,很容易忘记一些没有重新编译的小库.

有更多的标志来定义要绑定到的版本;它记录在 http://msdn.microsoft.com/en-us/library/cc664727%28v=vs.90%29.aspx.作为上面几行的替代,你也可以把

#define _BIND_TO_CURRENT_VCLIBS_VERSION 1

这将绑定到所有 VC 库(CRT、MFC、ATL、OpenMP)的最新版本.

然后,检查嵌入式清单的内容.下载 XM 资源编辑器:http://www.wilsonc.demon.co.uk/d10resourceeditor.htm.打开解决方案中的每个 dll 和 exe.在XP 主题清单"下查看.检查右侧的版本"属性是否为9.0.30729.1".如果是9.0.21022",则说明某些静态库正在拉入旧版本的清单.

我发现在很多情况下,两个版本都包含在清单中.这意味着某些库使用 sp1 版本,而其他库不使用.

调试哪些库没有设置预处理器指令的好方法:临时修改您的平台标头,以便在尝试嵌入旧清单时停止编译.打开 C:Program FilesMicrosoft Visual Studio 9.0VCcrtincludecrtassem.h.搜索21022"字符串.在那个定义中,放一些无效的东西(将定义"更改为blehbleh"左右).这样,当您编译未设置 _BIND_TO_CURRENT_CRT_VERSION 预处理器标志的项目时,您的编译将停止,您将知道需要添加它们或确保它在任何地方应用.

还要确保使用 Dependency Walker,以便您知道正在拉入哪些 dll.在虚拟机上安装没有更新的全新 Windows XP 副本(仅 SP2)是最简单的.这样您就可以肯定地知道 SxS 文件夹中没有任何东西被使用,而不是您提供的并排 dll.

Since our switch from Visual Studio 6 to Visual Studio 2008, we've been using the MFC90.dll and msvc[pr]90.dlls along with the manifest files in a private side-by-side configuration so as to not worry about versions or installing them to the system.

Pre-SP1, this was working fine (and still works fine on our developer machines). Now that we've done some testing post-SP1 I've been pulling my hair out since yesterday morning.

First off, our NSIS installer script pulls the dlls and manifest files from the redist folder. These were no longer correct, as the app still links to the RTM version.

So I added the define for _BIND_TO_CURRENT_VCLIBS_VERSION=1 to all of our projects so that they will use the SP1 DLLs in the redist folder (or subsequent ones as new service packs come out). It took me hours to find this.

I've double checked the generated manifest files in the intermediate files folder from the compilation, and they correctly list the 9.0.30729.1 SP1 versions. I've double and triple checked depends on a clean machine: it all links to the local dlls with no errors.

Running the app still gets the following error:

The application failed to initialize properly (0xc0150002). Click on OK to terminate the application.

None of the searches I've done on google or microsoft have come up with anything that relates to my specific issues (but there are hits back to 2005 with this error message).

Any one had any similar problem with SP1?

Options:

  • Find the problem and fix it so it works as it should (preferred)
  • Install the redist
  • dig out the old RTM dlls and manifest files and remove the #define to use the current ones. (I've got them in an earlier installer build, since Microsoft blasts them out of your redist folder!)

Edit: I've tried re-building with the define turned off (link to RTM dlls), and that works as long as the RTM dlls are installed in the folder. If the SP1 dlls are dropped in, it gets the following error:

c:Program Files......X.exe

This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.

Has no-one else had to deal with this issue?

Edit: Just for grins, I downloaded and ran the vcredist_x86.exe for VS2008SP1 on my test machine. It works. With the SP1 DLLs. And my RTM linked app. But NOT in a private side-by-side distribution that worked pre-SP1.

解决方案

I have battled this problem myself last week and consider myself somewhat of an expert now ;)

I'm 99% sure that not all dlls and static libraries were recompiled with the SP1 version. You need to put

#define _BIND_TO_CURRENT_MFC_VERSION 1
#define _BIND_TO_CURRENT_CRT_VERSION 1

into every project you're using. For every project of a real-world size, it's very easy to forget some small lib that wasn't recompiled.

There are more flags that define what versions to bind to; it's documented on http://msdn.microsoft.com/en-us/library/cc664727%28v=vs.90%29.aspx . As an alternative to the lines above, you can also put

#define _BIND_TO_CURRENT_VCLIBS_VERSION 1

which will bind to the latest version of all VC libs (CRT, MFC, ATL, OpenMP).

Then, check what the embedded manifest says. Download XM Resource Editor: http://www.wilsonc.demon.co.uk/d10resourceeditor.htm. Open every dll and exe in your solution. Look under 'XP Theme Manifest'. Check that the 'version' attribute on the right-hand side is '9.0.30729.1'. If it's '9.0.21022', some static library is pulling in the manifest for the old version.

What I found is that in many cases, both versions were included in the manifest. This means that some libraries use the sp1 version and others don't.

A great way to debug which libraries don't have the preprocessor directives set: temporarily modify your platform headers so that compilation stops when it tries to embed the old manifest. Open C:Program FilesMicrosoft Visual Studio 9.0VCcrtincludecrtassem.h. Search for the '21022' string. In that define, put something invalid (change 'define' to 'blehbleh' or so). This way, when you're compiling a project where the _BIND_TO_CURRENT_CRT_VERSION preprocessor flag is not set, your compilation will stop and you'll know that you need to add them or made sure that it's applied everywhere.

Also make sure to use Dependency Walker so that you know what dlls are being pulled in. It's easiest to install a fresh Windows XP copy with no updates (only SP2) on a virtual machine. This way you know for sure that there is nothing in the SxS folder that is being used instead of the side-by-side dlls that you supplied.

相关文章