为什么在一台机器上开发并在另一台机器上运行EXE时,安装vcredist_x86.exe不能解决SideBySide错误?

42

问题

我使用 Microsoft Visual Studio 2005 Version 8.0.50727.762 (SP.050727-7600) 在 Windows XP Professional Version 2002 Service Pack 3 上编写了一个名为 'Foo' 的 C ++ 项目。我将该项目构建为 Foo.exe。然后,我将文件 Foo.exe 复制到 Windows Server 2003 Enterprise Edition Service Pack 2。当我尝试运行它时,出现以下错误:

C:\foo.exe
The application has failed to start because the application configuration is incorrect.
Reinstalling the application may fix the problem.

在事件查看器 > 系统中,记录了三个事件。

事件 ID:32;来源:SideBySide

Dependent Assembly Microsoft.VC80.CRT could not be found and Last Error was
The referenced assembly is not installed on your system.

事件 ID:59;来源:SideBySide

Resolve Partial Assembly failed for Microsoft.VC80.CRT.
Reference error message: The referenced assembly is not installed on your system.

事件 ID:59;来源:SideBySide

Generate Activation Context failed for C:\foo\Foo.exe.
Reference error message: The referenced assembly is not installed on your system.
安装Microsoft Visual C++ 2005 Redistributable未解决问题。
  1. http://www.microsoft.com/download/en/details.aspx?id=3387下载vcredist_x86.exe
  2. 安装它。 安装程序创建了一个名为C:\windows\winsxs\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0de06acd的文件夹。

从“添加或删除程序”中找到此软件的版本为“8.0.50727.42”。

尝试运行C:\foo\foo.exe时,我得到了我上面描述的相同错误。

安装Microsoft Visual C++ 2005 SP1 Redistributable未解决问题。
  1. http://www.microsoft.com/download/en/details.aspx?id=5638下载vcredist_x86.exe
  2. 安装它。 安装程序创建了一个名为C:\windows\winsxs\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_6b128700的文件夹。

从“添加或删除程序”中找到此软件的版本为“8.0.56336”。

尝试运行C:\foo\foo.exe时,我得到了我上面描述的相同错误。

从同一台机器(我运行EXE的机器)复制CRT DLL和清单未解决问题。
  1. 我将C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0de06acd中的msvcm80.dllmsvcp80.dllmsvcr80.dll复制到C:\foo
  2. 然后,我将C:\WINDOWS\WinSxS\Manifests\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0de06acd.manifest复制到C:\foo并将其重命名为Microsoft.VC80.CRT.manifest

清单文件的第四行如下:

<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.42"
                  processorArchitecture="x86"
                  publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
当我尝试运行C:\foo\foo.exe时,这次它没能成功。我用位于C:\windows\winsxs\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_6b128700的DLL文件和相应的清单文件再次重复了此操作,但仍然没有帮助。我得到了相同的错误。
在这两种情况下,我在事件查看器 > 系统中获得了以下错误。
事件 ID:34;来源:SideBySide
Component identity found in manifest does not match the identity of the component requested

事件ID:58;来源:SideBySide

Syntax error in manifest or policy file "C:\foo\Microsoft.VC80.CRT.MANIFEST" on line 4.

事件 ID:59;来源:SideBySide

Generate Activation Context failed for C:\foo\Foo.exe. Reference error message: The manifest file contains one or more syntax errors.

从Windows XP机器(我编译EXE的地方)复制CRT DLL和清单并不能解决问题。

  1. 我将C:\winnt\winsxs\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_6b128700中的msvcm80.dllmsvcp80.dllmsvcr80.dll从Windows XP机器(我开发和构建foo.exe的地方)复制到Windows Server 2003机器(我正在尝试运行foo.exe的地方)的C:\foo目录。
  2. 接下来,我将C:\\winnt\\winsxs\\Manifests\\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_6b128700.manifest复制到C:\\foo目录,并将其重命名为Microsoft.VC80.CRT.manifest

清单文件的第四行如下所示:

<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.762"
                  processorArchitecture="x86"
                  publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>

尝试运行 C:\foo\foo.exe 时,我遇到了与前面一节提到的相同的错误。

从 Visual Studio 文件夹中复制 CRT DLL 和清单解决了问题。

  1. 将 Windows XP 计算机(我在那里开发和构建 foo.exe)的 C:\Program Files\Microsoft Visual Studio 8\VC\redist\x86\Microsoft.VC80.CRT 中的 msvcm80.dllmsvcp80.dllmsvcr80.dllMicrosoft.VC80.CRT.manifest 复制到试图在其中运行它的 Windows Server 2003 计算机的 C:\foo 中。

清单文件的第四行如下所示:

<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.6195"
                  processorArchitecture="x86"
                  publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>

这次我能够在没有任何问题的情况下运行C:\foo\foo.exe。

问题

我原本以为按照第二种方法安装“Microsoft Visual C++ 2005 SP1 Redistributable”(vcredist_x86.exe)可以解决问题。但事实并非如此。从开发机器的 C:\Program Files\Microsoft Visual Studio 8\VC\redist\x86\Microsoft.VC80.CRT 文件夹中复制 DLL 和清单文件才解决了问题。为什么会这样呢?

构建选项

如果有帮助,以下是我从Visual Studio项目属性中选择的编译器和链接器选项:

配置属性>C/C++>命令行:

/O2 /GL /D "_MBCS" /FD /EHsc /MD /Fo"Release\\" /Fd"Release\vc80.pdb" /W3 /nologo /c /Wp64 /Zi /TP /errorReport:prompt

配置属性>链接器>命令行:

/OUT:"C:\MixedBag\Release\Foo.exe" /NOLOGO /MANIFEST /MANIFESTFILE:"Release\Foo.exe.intermediate.manifest" /DEBUG /PDB:"c:\MixedBag\release\Foo.pdb" /OPT:REF /OPT:ICF /LTCG /MACHINE:X86 /ERRORREPORT:PROMPT kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib


4
从版本号就可以看出来。你的开发机的修订版本是6195,但你使用的redist版本非常旧:42和762.自SP1以来有几个安全补丁。最简单的方法就是创建一个安装程序项目。 - Hans Passant
1
这可能是你正在寻找的东西。点击此处 - Luke
找出我构建所需的redist版本最简单的方法是检查Visual Studio在构建项目时创建的清单文件。我的清单文件位于C:\Foo\Release\Foo.exe.intermediate.manifest。我已在下面的答案中详细说明了它。 - Susam Pal
7个回答

52

我将回答自己的问题。来自Hans Passant和Luke的评论帮了我很多。

我下载了Microsoft Visual C++ 2005 Service Pack 1 Redistributable Package MFC Security Update并在我尝试运行 C:\foo\foo.exe的系统上安装了它。在此之后,EXE文件可以正常运行。

安装程序将CRT DLLs放置在C:\windows\winsxs\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.6195_x-ww_44262b86中。因此,正如Hans Passant所说,8.0.50727.6195是我正在寻找的CRT DLLs的版本。

找到这个版本最简单的方法是查看Visual Studio在开发系统上构建我的项目时生成的清单文件。我的清单文件位于C:\Foo\Release\Foo.exe.intermediate.manifest。它有一个类似于这样的标签:

<assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50727.6195'
                  processorArchitecture='x86'
                  publicKeyToken='1fc8b3b9a1e18e3b' />

所以,这表明我需要8.0.50727.6195版本的DLL。其余的就是寻找正确的vcredist_x86.exe,它恰好在我在第二段提到的URL中。那个URL页面包含一个链接到KB2538242,其中显示了安装程序将安装的DLL的版本号。

注意:正如Elie在另一个回答中提到的,由于这是一个32位应用程序,必须在运行该应用程序的系统上安装vcredist_x86.exe(而不是vcredist_x64.exe),无论该系统是32位Windows系统还是64位Windows系统。再次强调,.manifest文件在processorArchitecture属性中提供了这个提示。


非常感谢您!三年后,您解决了我确切的问题! - Carl Kevinson
您还可以从xstrace.exe工具中获取dll版本,如此处所述。 - rrosa

4
这里是解决此问题的方法:
如果应用程序是32位的,并且您尝试在安装了VC_REDISTx64的64位操作系统上运行它,您仍然会收到sidebyside错误。
简单的解决方案是,在64位操作系统上还必须加载VC_REDISTx86。

这是一个非常好的观点。谢谢你分享。现在,我已经在我的回答中添加了有关处理器架构的注释。 - Susam Pal

4

3
感谢您的答复。这个问题已经在5个月前得到了解答。 - Susam Pal

3

虽然我的应用程序是在Win 2k8 R2 x64上使用vs2008(该环境下的C:\ Program Files(x86)\ Microsoft Visual Studio 9.0 \ VC \ redist \ amd64 \ Microsoft.VC90.CRT中有msvcm90.dll,msvcp90.dll和msvcr90.dll)开发的,

但它可以在win 2k3 SP2 x64上运行,

但需要msvcm80.dll,msvcp80.dll和msvcr80.dll。

安装Microsoft Visual C++ 2005 SP1 Redistributable Package (x86)后,应用程序可以正确安装和运行。


3
我遇到了一个有些相关的问题。两台安装了VS2005的开发XP机器,称为A和B。我在A上进行开发、构建和运行。然后我将整个项目复制到B上,在那里进行构建。尝试运行时,出现了SusamPal提到的相同错误消息。我意识到B的WinSxS中有x86_Microsoft.VC80.CRT_xxx清单(和文件夹),但没有相应的x86_Microsoft.VC80.DebugCRT_xxx清单(为什么?!)。我尝试了SusamPal描述的几种跳舞和咒语,但无济于事。我通过从A的WinSxS中复制相应的文件夹到B,并从WinSxs\Manifests中复制相应的清单来解决了问题。

不,就像我说的那样,我有“两台安装了VS2005的开发XP机器”。每台机器上都是完全相同的VS2005。 - user1752563

0

对我来说,侧边错误只需在设置c/c++ -> CodeGeneration-> RuntimeLibrary下更改,将其设置为MTD,即多线程调试。


-2
我们在这里真的遇到了一个问题:应用程序可执行文件使用清单机制引用dll文件。在很久以前,应用程序作者只是将所需的dll文件复制到系统目录中。不幸的是,这会导致所谓的“dll地狱”问题,即通过不兼容的新版本覆盖旧版本的dll可能导致应用程序停止工作。微软随后提出了版本化的想法(winsxs)。
不幸的是,这是一个相当复杂的机制,手动安装dll文件(程序集)到sxs文件夹绝对不是一个好主意。安装所谓的“可再发行包”也不是一个完美的解决方案。
此外,当我们需要调试版本时,这也无法帮助我们。由于微软禁止分发支持dll的调试版本,“可再发行包”不会安装它们。(请注意,程序集id依赖于当前VS2005的子版本,并与已安装的支持库相关。)
通常,VS安装程序会将所需的程序集添加到系统中,但随着时间的推移,安装更新或较新的SDK和工具可能会破坏这种正确状态。
假设我们有这样的情况——我们的调试库不再集成到系统中。假设我们有一个带有项目A和活动调试配置的工作区,导致应用程序无法正常工作。然后我们可以在当前工作区中创建安装程序项目C,将我们的应用程序(或者严格来说,具有活动配置的项目)添加到其中。设置安装程序项目以将我们的可执行文件放置在某个位置(桌面是关于此情况的正确位置),启用依赖项检查和一些其他次要属性。然后构建项目C并运行安装程序(或使用上下文菜单从VS中“安装”)。现在您的应用程序和使用调试dll库创建的其他应用程序开始工作。
当您使用“删除”选项运行安装程序时,请注意回到先前的情况。这里有一篇与分发主题相关的好文章:http://blogs.msdn.com/b/vcblog/archive/2007/10/12/how-to-redistribute-the-visual-c-libraries-with-your-application.aspx
如果您有其他应用程序,并希望通过简单复制部署它们,可能是在没有安装VS的非开发机器上,您可以创建虚拟项目以及适当的配置和安装程序。然后在每台机器上安装一次,然后复制您正在处理的可执行文件。

1
你能添加一些换行吗?那几乎不可能读。 - Cleb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接