【问题标题】:Resolving MSB3247 - Found conflicts between different versions of the same dependent assembly解决 MSB3247 - 发现同一依赖程序集的不同版本之间存在冲突
【发布时间】:2010-12-24 16:08:00
【问题描述】:

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

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

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

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

【问题讨论】:

  • 就我而言,我只需要确保解决方案中的所有项目都运行相同版本的 nuget 包(可以简单地将所有项目更新到最新版本)。

标签: .net msbuild clr ndepend


【解决方案1】:

将“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 Reflector。

【讨论】:

  • 您的解决方案对我来说看起来不错,但是我认为使用“参考”部分查看版本号并不总是有用的。我经常看到 VS 对我“撒谎”它使用的是哪个版本,而 .csproj 文件中实际上提到了哪个版本。
  • @David Gardiner - 在使用 C# 项目时,我同意您的“撒谎”声明。根据我的经验,C# 项目可能会对引用的版本和编译/链接的实际版本感到困惑。发生这种情况时,我清理解决方案,手动删除 bin 和 obj 文件夹,然后删除 %APPDATA% 中的临时项目程序集。重建解决方案通常可以解决问题。 (VB 很少遇到这个特定问题。)
  • 赢得告诉人们实际使用输出窗口。构建不仅仅是 F5 + 错误列表窗口。
  • 正如 ErikHeemskerk 在他的回答中提到的,在 Visual Studio 2010 中,您需要将输出详细程度设置为详细才能查看 ResolveAssemblyReferences 的输出。
  • 提示:要在详细构建输出中找到确切位置,请将文本复制到文本编辑器中,搜索“发现同一依赖程序集的不同版本之间的冲突。”。
【解决方案2】:

Mike Hadlow 的 posted a little console app called 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 警告问题的一种更快的方法。

【讨论】:

  • AsmSpy 很棒,您只需要记住您正在寻找对具有不匹配版本的第三方 DLL 的引用。通常,标准库引用中的不匹配版本不会导致这些警告(您会经常看到它们)。
  • 这是一个很棒的小工具,它帮助我立即解决了我的问题。然而,就我而言,它并不完全是第三方 DLL,而是对 System.Management.Automation.dll 的引用,它对 mscorlib.dll 有不同的引用。
  • 这个工具很不错,但是,它并不适用于所有情况。至少对于 .NET 4.5 项目,它没有为我显示冲突引用版本。 + msbuild 输出用路径和所有命名有问题的 DLL。
  • 谢谢你们的好话:)
  • 您刚刚为我节省了几个小时的工作时间!它确实有助于阅读详细的输出,但是一旦我这样做了,就很容易再次使用您的工具进行验证。
【解决方案3】:

有时@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...

Visual Studio 2013

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

    • 转到工具->选项->项目和解决方案->构建并运行以设置输出详细程度。
    【解决方案5】:

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

    1. 右键解决方案
    2. 点击管理 Nuget 包
    3. 合并选项卡并更新到相同版本。

    【讨论】:

      【解决方案6】:

      为默认的 ASP.NET MVC 4 beta 生成此警告 see here

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

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

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

      【讨论】:

      • 我跟着这个,错误消失了。仍然不知道如何或为什么,我用 VS2010 开始了一个 MVC 4 项目,然后在 VS2012 上迁移。但是,添加版本属性,使错误消失。谢谢
      【解决方案7】:

      使用依赖阅读器

      使用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。尝试以下方法之一

      【讨论】:

        【解决方案8】:

        我也遇到了这个问题,并使用 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 版本即可。

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

        【讨论】:

          【解决方案9】:

          我根据Mike Hadlow application: AsmSpy做了一个申请。

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

          代码位于:GitHub

          【讨论】:

            【解决方案10】:

            快速修复:

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

            【讨论】:

            • 这应该是最佳答案。为整个解决方案整合 NuSet 可让您查看问题所在并毫无问题地更新它们
            【解决方案11】:

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

            【讨论】:

              【解决方案12】:

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

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

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

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

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

              【讨论】:

                【解决方案13】:

                有时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 Binary and Structured Log Viewer 并且只为发出警告的项目中的冲突生成绑定重定向(即,仅将那些 there was a conflict 行传递到上述代码的输入文本文件 [AssemblyConflicts.txt]) .

                【讨论】:

                  【解决方案14】:

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

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

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

                  【讨论】:

                    【解决方案15】:

                    Visual Studio for Mac 社区添加:

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

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

                    位于 Visual Studio 社区 → 首选项... → 项目 → 构建日志 → 详细程度

                    【讨论】:

                      【解决方案16】:

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

                      【讨论】:

                        猜你喜欢
                        • 2013-09-27
                        • 2014-09-06
                        • 2013-05-22
                        • 2010-09-06
                        • 2014-06-26
                        • 2017-09-20
                        相关资源
                        最近更新 更多