. net 3.5解决方案在使用msbuild编译时出现此警告。

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

我确实尝试使用VS 2010 Beta 2的MSBUILD(连接文章指出这在CLR的下一个版本中得到了修复),但也没有提供更多的细节(可能是在Beta 2后修复的)。

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


当前回答

有时候@AMissico的答案是不够的。在我的例子中,我在Output窗口中找不到错误,所以我决定创建一个日志文件并分析它,执行以下步骤:

将构建日志保存到一个文件…https://msdn.microsoft.com/en-us/library/ms171470.aspx msbuild MyProject的。proj /fl /flp:logfile=MyProjectOutput.log 查找文本:警告MS…或者具体的警告信息:(例如,第9293行)发现不同版本之间存在冲突…和冲突错误的完整细节将在此消息的上面(例如,第9277行)。

Visual Studio 2013

其他回答

最简单的方法是不考虑(内部)依赖关系:

打开“解决方案资源管理器”。 点击“显示所有文件” 扩大“引用” 您将看到一个(或多个)引用与其他引用的图标略有不同。通常情况下,它会有一个黄色的方框,建议你记下它。把它拿掉。 重新添加引用并编译代码。 这是所有。

在我的例子中,MySQL引用有一个问题。以某种方式,我可以在所有可用引用的列表下列出它的三个版本。我遵循了上面的方法1到6,它对我很有效。

将“MSBuild项目构建输出详细信息”更改为“详细信息”或以上。要做到这一点,请遵循以下步骤:

Bring up the Options dialog (Tools -> Options...). In the left-hand tree, select the Projects and Solutions node, and then select Build and Run. Note: if this node doesn't show up, make sure that the checkbox at the bottom of the dialog Show all settings is checked. In the tools/options page that appears, set the MSBuild project build output verbosity level to the appropriate setting depending on your version: Diagnostics when on VS2012, VS2013 or VS2015 (the message in these versions says you should use "Detailed", but this is plain wrong, you should use "Diagnostics") Detailed when you're on VS2010 Normal will suffice in VS2008 or older. Build the project and look in the output window.

检查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.

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

您可以检查每个引用的属性。 打开项目属性并检查References部分的版本。 使用文本编辑器打开项目。 使用. net Reflector。

快速修复:

右键单击解决方案->管理解决方案->的NuGet包在巩固下,你可以看到是否有不同版本的相同的包被安装。卸载不同版本,安装最新版本。

有时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二进制和结构化日志查看器,并仅为发出警告的项目中的冲突生成绑定重定向(也就是说,仅超过上述代码[AssemblyConflicts.txt]的输入文本文件的冲突行)。

使用依赖项阅读器

使用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

将父节点和子节点放在一列中(默认情况下,每行包含一个父节点和一个子节点,以表示这个父节点依赖于那个子节点) 然后使用关联数组进行一种“group by”

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

$ 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,你需要在运行awkward和grep之前下载一个。试试下面的一种方法

CMDER + awk + dep.exe Gitbash + awk + dep.exe 天鹅座+德.exe