432

使用 msbuild 编译时,.NET 3.5 解决方案最终会出现此警告。

有时 NDepend 可能会有所帮助,但在这种情况下,它没有提供任何进一步的细节。像 Bob 一样,我最终不得不求助于在 ILDASM 中打开每个程序集,直到找到引用旧版本的依赖程序集的程序集。

我确实尝试使用 VS 2010 Beta 2 中的 MSBUILD(因为 Connect 文章指出这已在 CLR 的下一版本中修复),但也没有提供更多细节(可能在 Beta 2 后修复)

有没有更好(更自动化)的方法?

4

16 回答 16

585

将“MSBuild 项目构建输出详细程度”更改为“详细”或更高。为此,请按照下列步骤操作:

  1. 调出选项对话框(工具 -> 选项...)。
  2. 在左侧树中,选择Projects and Solutions节点,然后选择Build and Run
    • 注意:如果此节点未显示,请确保选中对话框底部的复选框显示所有设置
  3. 在出现的工具/选项页面中,根据您的版本将MSBuild 项目构建输出详细级别设置为适当的设置:

  4. 构建项目并查看输出窗口。

查看 MSBuild 消息。该ResolveAssemblyReferences任务是 MSB3247 的起源任务,应该可以帮助您调试此特定问题。

我的具体情况是对 SqlServerCe 的错误引用。见下文。我有两个项目引用了两个不同版本的 SqlServerCe。我去了旧版本的项目,删除了引用,然后添加了正确的引用。

Target ResolveAssemblyReferences:
    Consider app.config remapping of assembly "System.Data.SqlServerCe, ..." 
        from Version "3.5.1.0" [H:\...\Debug\System.Data.SqlServerCe.dll] 
        to Version "9.0.242.0" [C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PublicAssemblies\System.Data.SqlServerCe.dll]
        to solve conflict and get rid of warning.
    C:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets : 
        warning MSB3247: Found conflicts between different versions of the same dependent assembly.

您不必打开每个程序集来确定引用程序集的版本。

  • 您可以检查每个参考的属性。
  • 打开项目属性并检查参考部分的版本。
  • 使用文本编辑器打开项目。
  • 使用 .Net 反射器。
于 2010-01-30T21:23:56.630 回答
140

Mike Hadlow发布了一个名为 AsmSpy 的小控制台应用程序,它很好地列出了每个程序集的引用:

Reference: System.Net.Http.Formatting
        4.0.0.0 by Shared.MessageStack
        4.0.0.0 by System.Web.Http

Reference: System.Net.Http
        2.0.0.0 by Shared.MessageStack
        2.0.0.0 by System.Net.Http.Formatting
        4.0.0.0 by System.Net.Http.WebRequest
        2.0.0.0 by System.Web.Http.Common
        2.0.0.0 by System.Web.Http
        2.0.0.0 by System.Web.Http.WebHost

与依赖 MSBuild 输出相比,这是了解 MSB3247 警告底部的更快方法。

于 2012-03-30T20:35:18.927 回答
24

有时@AMissico 的回答是不够的。就我而言,我在“输出”窗口中找不到错误,因此我决定创建一个日志文件并进行分析,方法是执行以下步骤:

  1. 将构建日志保存到文件... https://msdn.microsoft.com/en-us/library/ms171470.aspx

    msbuild MyProject.proj /fl /flp:logfile=MyProjectOutput.log;verbosity=detailed

  2. 查找文本:warning MS...或特定警告信息:(例如第 9293 行)Found conflicts between different versions...,冲突错误的完整详细信息将在此消息的上方(例如第 9277 行)There was a conflicts between... 查找错误信息

视觉工作室 2013

于 2015-09-10T21:07:51.477 回答
21

我发现(至少在 Visual Studio 2010 中)您需要将输出详细程度至少设置为“详细”才能发现问题。

可能我的问题是以前是 GAC 参考的参考,但在我的机器重新安装后不再是这种情况。

于 2010-06-16T14:59:45.817 回答
9

我有同样的错误,无法用其他答案弄清楚。我发现我们可以“整合”NuGet 包。

  1. 右键单击解决方案
  2. 单击管理 Nuget 包
  3. 合并选项卡并更新到相同版本。
于 2017-02-19T22:08:22.313 回答
7

此警告为默认 ASP.NET MVC 4 beta 生成, 请参见此处

在中,可以通过手动编辑项目的 .csproj 文件来消除此警告的任何强制转换。

修改............:参考 Include="System.Net.Http"

阅读......:参考 Include="System.Net.Http, Version=4.0.0.0"

于 2012-04-25T09:02:45.560 回答
6

使用依赖阅读器

使用dep.exe,您可以列出整个文件夹的所有嵌套依赖项。结合 grep 或 awk 等 unix 工具,它可以帮助您解决问题

查找在多个版本中引用的程序集

$ dep | awk '{ print $1 " " $2; print $4 " " $5 }' | awk '{ if (length(versions[$1]) == 0) versions[$1] = $2; if (versions[$1] != $2) errors[$1] = $1; }  END{ for(e in errors) print e } ' 
System.Web.Http            

这个晦涩的命令行运行 dep.exe 然后将输出两次通过管道传递到 awk 到

  • 将父项和子项放在一个列中(默认情况下,每行包含一个父项和一个子项,以表示该父项依赖于该子项这一事实)
  • 然后使用关联数组进行一种“分组”

了解这个组件是如何被拉进你的垃圾箱的

$ dep myproject/bin | grep -i System\.Web\.Http
MyProject-1.0.0.0 >> System.Web.Http.Web-5.2.3.0 2 ( FooLib-1.0.0.0 )
MyProject-1.0.0.0 >> System.Web.Http.Web-4.0.0.0 2 ( BarLib-1.0.0.0 )
FooLib-1.0.0.0 > System.Web.Http.Web-5.2.3.0 1
BarLib-1.0.0.0 > System.Web.Http.Web-4.0.0.0 1 

在此示例中,该工具将向您显示 System.Web.Http 5.2.3 来自您对 FooLib 的依赖,而 4.0.0 版本来自 BarLib。

然后你可以选择

  • 说服库的所有者使用相同的版本
  • 停止使用其中之一
  • 在配置文件中添加绑定重定向以使用最新版本

如何在 Windows 中运行这些东西

如果您没有 unix 类型的 shell,则需要先下载一个,然后才能运行awkgrep. 尝试以下方法之一

于 2016-01-06T15:49:15.893 回答
4

我也遇到了这个问题,并使用了 AMissico 的建议来发现问题(尽管必须将详细级别设置为详细。

在找到罪魁祸首之后,问题实际上很简单。

背景:我将我的项目从 VS2008 升级到 VS2010。在 VS2008 中,目标框架是 3.5,当我将它带入 VS2010 时,我将其切换为 4(完整)。我还升级了一些第三方组件,包括 Crystal 报表。

事实证明,大多数系统引用都指向版本 4.0.0.0,但有几个没有自动更改(System 和 System.Web.Services)并且仍在查看 2.0.0.0。Crystal 报表引用 4.0.0.0,因此这是发生冲突的地方。只需将光标放在解决方案资源管理器中的第一个系统库上,将光标向下移动并查找对 2.0.0.0 的任何引用,删除并重新添加较新的 4.0.0.0 版本就可以了。

奇怪的是,大多数参考资料都已正确更新,如果不是水晶报表,我可能永远不会注意到...

于 2010-11-02T17:15:31.047 回答
2

如此处所述,您需要删除未使用的引用,警告就会消失。

于 2012-07-02T07:57:34.870 回答
2

我基于Mike Hadlow 应用程序制作了一个应用程序:AsmSpy

我的应用程序是一个带有 GUI 的 WPF 应用程序,可以从我的家庭网络服务器下载:AsmSpyPlus.exe

代码可在:GitHub

桂样

于 2015-08-18T18:44:19.657 回答
2

快速解决:

右键单击解决方案 -> 管理解决方案的 NuGet 包 -> 在合并下,您可以查看是否安装了同一包的不同版本。卸载不同版本并安装最新版本。

于 2017-08-04T13:02:46.360 回答
1

ASP.NET 构建管理器通过按字母顺序浏览文件夹来构建网站,并且对于每个文件夹,它会计算出它的依赖关系并首先构建依赖关系,然后是选定的文件夹。

在这种情况下,有问题的文件夹是 ~/Controls,被选择在开始时构建,由于未知原因,它在那里构建一些控件作为单独的程序集,而不是在与其他控件相同的程序集中(似乎与某些控件依赖于同一文件夹中的其他控件这一事实有关)。

然后构建的下一个文件夹(~/File-Center/Control)依赖于根文件夹~/,它依赖于~/Controls,所以文件夹~/Controls再次被构建,只是这次是分开的控件到它们自己的程序集现在与其他控件连接到同一程序集,但仍引用分离的程序集。

因此,此时 2 个程序集(至少)具有相同的控件并且构建失败。

虽然我们仍然不知道为什么会发生这种情况,但我们可以通过将 Controls 文件夹名称更改为 ZControls 来解决它,这样它就不会在 ~/File-Center/Control 之前构建,只有在它之后并且这样构建正如它应该。

于 2011-04-29T21:05:01.253 回答
1

有时AutoGenerateBindingRedirects是不够的(即使有GenerateBindingRedirectsOutputType)。搜索所有There was a conflict条目并逐个手动修复它们可能很乏味,因此我编写了一小段代码来解析日志输出并为您生成它们(转储到stdout):

// Paste all "there was a conflict" lines from the msbuild diagnostics log to the file below
const string conflictFile = @"C:\AssemblyConflicts.txt";

var sb = new StringBuilder();
var conflictLines = await File.ReadAllLinesAsync(conflictFile);
foreach (var line in conflictLines.Where(l => !String.IsNullOrWhiteSpace(l)))
{
    Console.WriteLine("Processing line: {0}", line);

    var lineComponents = line.Split('"');
    if (lineComponents.Length < 2) 
        throw new FormatException("Unexpected conflict line component count");

    var assemblySegment = lineComponents[1];
    Console.WriteLine("Processing assembly segment: {0}", assemblySegment);
    var assemblyComponents = assemblySegment
                              .Split(",")
                              .Select(kv => kv.Trim())
                              .Select(kv => kv.Split("=")
                              .Last())
                              .ToArray();

    if (assemblyComponents.Length != 4) 
        throw new FormatException("Unexpected conflict segment component count");

    var assembly = assemblyComponents[0];
    var version = assemblyComponents[1];
    var culture = assemblyComponents[2];
    var publicKeyToken = assemblyComponents[3];

    Console.WriteLine("Generating assebmly redirect for Assembly={0}, Version={1}, Culture={2}, PublicKeyToken={3}", assembly, version, culture, publicKeyToken);
    sb.AppendLine($"<dependentAssembly><assemblyIdentity name=\"{assembly}\" publicKeyToken=\"{publicKeyToken}\" culture=\"{culture}\" /><bindingRedirect oldVersion=\"0.0.0.0-{version}\" newVersion=\"{version}\" /></dependentAssembly>");
}

Console.WriteLine("Generated assembly redirects:");
Console.WriteLine(sb);

提示:使用MSBuild 二进制和结构化日志查看器,并且只为发出警告的项目中的冲突生成绑定重定向(即,仅将这些there was a conflict行传递到上述代码的输入文本文件 [ AssemblyConflicts.txt])。

于 2019-08-07T15:15:54.990 回答
0

一种最简单的方法,无需考虑(内部)依赖关系:

  1. 打开“解决方案资源管理器”。
  2. 点击“显示所有文件”
  3. 展开“参考”
  4. 您会看到一个(或多个)参考,其图标与其他参考略有不同。通常,它带有黄色框,建议您记下它。只需将其删除。
  5. 添加引用并编译您的代码。
  6. 就这样。

就我而言,MySQL 参考存在问题。不知何故,我可以在所有可用参考列表下列出它的三个版本。我遵循了上面的过程 1 到 6,它对我有用。

于 2014-06-15T05:33:55.203 回答
0

Visual Studio for Mac 社区补充:

由于AMissico 的回答需要更改日志级别,并且 ASMSpy 和 ASMSpyPlus 都不能用作跨平台解决方案,因此这里是 Visual Studio for Mac 的简短补充:

https://docs.microsoft.com/en-us/visualstudio/mac/compiling-and-building

它在Visual Studio Community → Preferences... → Projects → Build Log → verbosity

于 2018-05-15T02:10:42.617 回答
0

如果您有 reshaper,请删除解决方案中所有未使用的参考。

于 2019-07-09T15:16:14.933 回答