错误 MSB3171:生成清单时出现问题

Posted

技术标签:

【中文标题】错误 MSB3171:生成清单时出现问题【英文标题】:error MSB3171: Problem generating manifest 【发布时间】:2011-06-07 15:38:17 【问题描述】:

C:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets(2341,9): error MSB3171: Problem generating manifest. Could not load file or assembly '...CppCli.dll.manifest' or one of its dependencies. An attempt was made to load a program with an incorrect format.

我在编译 CSharp 项目时遇到此错误,其中:

CSharp 项目

一个 VS2008 C# 项目,添加 CppCli 项目作为参考

Output type, Windows application
Platform target, Any CPU
I've also tried with Platform target, x86

CppCli 项目

链接到外部 C++ 静态库的 VS2008 C++/CLI 项目

Targeted framework .NET Framework 3.5
Configuration type, Dynamic Library (.dll)
Configuration properties, Common Language Runtime support, /clr
Manifest tool, Embed manifest, No

安装的软件(我了解VS2008+SP1和.NET3.5+SP1)

Microsoft Visual C++ 2005 Redistributable KB2467175
Microsoft Visual C++ 2008 Redistributable KB2467174 x86 9.0.30729.5570
Microsoft Visual C++ 2008 Redistributable x86 9.0.21022
Microsoft Visual C++ 2008 Redistributable x86 9.0.30729.4974

更多细节 - 为 CppCli 生成嵌入式清单,CSharp 构建正确。 - Microsoft.Common.targets 的第 2341 行是关于 GeneralApplicationManifest 的标记 - CppCli.intermediate.manifest 指向 Microsoft.VC90.DebugCRT.dll 9.0.30729.4148 - CppCli.manifest 指向 9.0.21022.8 - C:\Archivos de programa\Microsoft Visual Studio 9.0\VC\redist\Debug_NonRedist\x86\Microsoft.VC90.DebugCRT\Microsoft.VC90.DebugCRT.manifest 显示 9.0.30729.4148 版本 - 手动更改 CppCli.manifest 以指向 9.0.30729.4148,查询 C:\MyProject\Microsoft.VC90.DebugCRT.dll.manifest 时,procmon 跟踪显示 NAME NOT FOUND。显然,CRT 清单不存在。关键是我没有找到任何查询 CRT 清单所在的 C:\Archivos de programa...\Microsoft.VC90.DebugCRT.dll.manifest 的跟踪。

问题 所以我在这里似乎遇到了两个问题:第一,清单生成。为此,我找到了这个链接,虽然我不知道它会有多大用处:http://www.eggheadcafe.com/software/aspnet/33380343/compiling-32bit-application-x86-in-vs2008-vc2008-on-vista-64bit----x64.aspx。它说您必须在每个编译单元中使用定义。其次,现在对我来说最重要的是,为什么手动更改 CppCli.manifest 我仍然无法构建 CSharp 项目。

编辑 我已经将项目移动到VS2010,使用工具向导,我仍然有同样的问题。

编辑 2011/06/13 我现在要选择“使用嵌入式清单”选项。项目构建,但是当我尝试执行 CppCli 代码时,它说我没有运行有效的 Win32 应用程序。

编辑 2011/06/15 CppCli 项目正在链接到以下静态库:

YetAnother.lib
libcurl.lib
libboost_system-vc90-mt-gd-1_44.lib
libboost_thread-vc90-mt-gd-1_44.lib
libboost_filesystem-vc90-mt-gd-1_44.lib
libeay32MDd.lib
ssleay32MDd.lib
shlwapi.lib
ws2_32.lib
winmm.lib
wldap32.lib
winhttp.lib

依赖项是:

CppCli 使用 YetAnother。 YetAnother 是一个使用 curl 和 boost 线程和日期时间的 C++ 项目。 curl 使用 openssl。

我正在阅读 (http://marc.info/?l=boost-users&m=123425857320026) 静态链接的 boost 库根本无法使用 CLR 项目。所以我删除了那些libboost 行,并在CppCli 中使用BOOST_ALL_DYN_LINK,将boost_thread-vc90-mt-gd-1_44.libboost_date_time-vc90-mt-gd-1_44.lib 复制到YetAnother\Debug 目录。同样的错误。解决方案构建,但当我尝试执行 CppCli 代码时,它说我没有运行有效的 Win32 应用程序。

编辑 2011/06/16 放弃!我显然因为徒劳地取了微软的名字而受到惩罚。网上太多的 cmets 说 boost 静态库和 CLR 不兼容。我会将 CppCli 更改为不使用 CLR,并通过 P/Invoke 而不是 Interop 与 CSharp 通信。

编辑 2011/06/17 使用 P/Invoke 一切正常。

【问题讨论】:

似乎是一个简单的问题。您正在混合任何 CPU 和 x86 或 x64 二进制文件。将它们全部设置到特定平台,它应该会消失。 @Ritch Melton - 没什么,将 CSharp 项目的平台目标更改为 x86 没有帮助。 尝试提高构建输出的详细程度,这可能会为您提供更多信息。转到工具->选项->项目和解决方案->构建和运行。在那里,您将看到两个组合:MSBuild 项目生成输出详细程度和 MSBuild 项目生成日志文件详细程度。根据需要更改它们,我更喜欢提高构建日志文件的详细程度,因为 html 更易于查看 @dario_ramos:这也没有帮助。当我运行应用程序时,我只收到一条错误消息,指出我要执行的代码不是有效的 Win32 应用程序。 可能问题出在您的外部非托管库中(即它可能已编译为 64 位)。尝试设置一个非托管 C++ 项目,一个 exe,它调用非托管库中的某些函数。看看你能不能运行它。 【参考方案1】:

我以前遇到过这个问题,这是因为不知何故,一堆 NGENed 程序集被损坏,不再被识别为有效的 64 位或 32 位程序集。我一开始是一个一个地删除 NGENed 的程序集,尝试加载另一个依赖时编译会失败;它一直到 mscorlib,此时我删除了所有 NGENed 程序集。之后一切都很好,一旦他们被重新 NGENed。

【讨论】:

@rturrado:它是原生图像生成器。它将程序集编译为本机代码并缓存结果。本机图像存储在 c:\windows\assembly\nativeImages_v*.* 下。我是说我认为您缓存的本机图像已损坏。找到损坏的本机映像并将其删除,或者完全删除 nativeImages 目录(因为可能有多个目录损坏,就像我的一样)。它们将由在特定时间运行的 NGEN 服务重建(它是一个 Windows 服务)。 Hein - 接受这个答案,因为它是唯一的一个!谢谢:)

以上是关于错误 MSB3171:生成清单时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

使用VS自带OpenMP时出现“错误 MSB6006 CL.exe 已退出,代码为2”

MSBuild 无法使用临时密钥签署 ClickOnce 清单(错误 MSB3326 和 MSB3321)

JPA 实体在实施物料清单概念时出现错误

应用程序构建成功但出现错误:运行映像时出现“没有主清单属性,在 app.jar 中”

错误 MSB6006:“CL.exe”以代码 2 退出

为啥我用VS2010调试程序时出现错误未能在指定文件夹中找到.exe