ChatGPT解决这个技术问题 Extra ChatGPT

Resolving MSB3247 - Found conflicts between different versions of the same dependent assembly

A .NET 3.5 solution ended up with this warning when compiling with msbuild.

Sometimes NDepend might help out but in this case it didn't give any further details. Like Bob I ended up having to resort to opening each assembly in ILDASM until I found the one that was referencing an older version of the dependant assembly.

I did try using MSBUILD from VS 2010 Beta 2 (as the Connect article indicated this was fixed in the next version of the CLR) but that didn't provide any more detail either (maybe fixed post Beta 2)

Is there a better (more automated) approach?

In my case I just had to make sure all the projects in the solution were running the same version of nuget packages (can simply update all to the latest).

C
Community

Change the "MSBuild project build output verbosity" to "Detailed" or above. To do this, follow these steps:

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.

Check out the MSBuild messages. The ResolveAssemblyReferences task, which is the task from which MSB3247 originates, should help you debug this particular issue.

My specific case was an incorrect reference to SqlServerCe. See below. I had two projects referencing two different versions of SqlServerCe. I went to the project with the older version, removed the reference, then added the correct reference.

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.

You do not have to open each assembly to determine the versions of referenced assemblies.

You can check the Properties of each Reference.

Open the project properties and check the versions of the References section.

Open the projects with a Text Editor.

Use .Net Reflector.


Your solutions looks good to me, however I don't think it is always useful to use the References section to view version numbers. I've often seen VS "lie" to me about which version it is using vs. which version is actually mentioned in the .csproj file.
@David Gardiner - I would agree with your "lying" statement when using C# projects. In my experience, C# projects can get confused regarding the referened version and the actual version compiled/linked. When this happens, I clean the solution, manually delete the bin and obj folders, then delete the temporary project assemblies in %APPDATA%. A rebuild solution usually resolves the problem. (VB rarely suffers from this specific problem.)
win for telling people to actually use the Output window. Build is so much more than F5 + Error List window.
As ErikHeemskerk mentioned in his answer, in Visual Studio 2010 you will need to set the output verbosity to detailed to see the output of ResolveAssemblyReferences.
Hint: to find the exact spot in the verbose build output, copy the text into a text editor, search for "Found conflicts between different versions of the same dependent assembly.".
K
Kirill Kobelev

Mike Hadlow has posted a little console app called AsmSpy that rather nicely lists each assembly's references:

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

This is a much quicker way to get to the bottom of the warning MSB3247, than to depend on the MSBuild output.


AsmSpy is awesome, you just need to remember that you're looking for the references to third party DLLs with mismatched versions. Generally, mismatched versions in references to the standard libraries won't cause these warnings (and you'll see them alot).
This is a great little tool which helped me solve my problem immediately. In my case, however, it wasn't exactly third party DLLs, but rather references to System.Management.Automation.dll which had different references to mscorlib.dll.
The tool is nice, however, it does not work in all circumstances. At least for a .NET 4.5 project it did not show the colliding references versions for me. + msbuild output names the DLLs in question with paths and all.
Thanks for the kind words guys :)
You just saved me some hours of work! It did help to read through the detailed output, but once I did it was easy to again verify with your tool.
J
Jaider

Sometime @AMissico answer is not enough. In my case, I couldn't find the error in the Output windows so I decided to create a log file and analyze it, by doing the following steps:

Saving the build log to a file... https://msdn.microsoft.com/en-us/library/ms171470.aspx msbuild MyProject.proj /fl /flp:logfile=MyProjectOutput.log;verbosity=detailed Find the text: warning MS... or the specific warning info: (e.g. line 9293) Found conflicts between different versions... and the full detail of the conflict error will be above of this message (e.g. line 9277) There was a conflicts between...

Visual Studio 2013


E
ErikHeemskerk

I found that (at least in Visual Studio 2010) you need to set the output verbosity to at least Detailed to be able to spot the problem.

It might be that my problem was a reference that was previously a GAC reference, but that was no longer the case after my machine's reinstall.


Go to Tools->Options->Projects and Solutions->Build and Run to set output verbosity.
C
Carol

I had the same error and could not figure it out with the other answers. I found that we can "Consolidate" NuGet packages.

Right click on the solution Click Manage Nuget Packages Consolidate tab and update to the same version.


C
Community

This warning generated for default ASP.NET MVC 4 beta see here

In, any cast this Warning can be eliminated by manually editing the .csproj file for your project. modify........: Reference Include="System.Net.Http" to read ......: Reference Include="System.Net.Http, Version=4.0.0.0"


I followed this and the error has disappeared. Still do not know how or why, I started an MVC 4 project with VS2010 then migrated on VS2012. However, adding the version attribute, made the error disappear. Thanks
C
Community

Use a dependency reader

Using dep.exe you can list out all the nested dependencies of an entire folder. Combined with unix tools like grep or awk, it can help you to solve your problem

Finding assemblies being referenced in more than one version

$ 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            

This obscure command line runs dep.exe then pipes the output twice to awk to

put the parent and child in a single column (by default each line contains one parent and a child to express the fact that this parent depends of that child)

then do a kind of 'group by' using an associative array

Understanding how this assembly got pulled in your bin

$ 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 

In this example, the tool would show you that System.Web.Http 5.2.3 comes from your dependency to FooLib whereas the version 4.0.0 comes from BarLib.

Then you have the choice between

convincing the owners of the libs to use the same version

stop using one them

adding binding redirects in your config file to use the latest version

How to run these thing in Windows

If you don't have a unix type shell you'll need to download one before being able to run awkand grep. Try one of the following

cmder + awk + dep.exe

gitbash + awk + dep.exe

cygwin + dep.exe


H
Hamiora

I had this problem too and used AMissico's advice too discover the problem (Although had to set verbosity level to Detailed.

The problem was actually quite straight forward though after finding the culprit.

Background: I upgraded my project from VS2008 to VS2010. In VS2008 the target framework was 3.5 and when I brought it into VS2010 I switched it to 4 (Full). I also upgraded some third party components including Crystal reports.

It turned out most of System references where pointing at version 4.0.0.0 but a couple had not been automatically changed (System and System.Web.Services) and were still looking at 2.0.0.0. Crystal reports is referencing 4.0.0.0 and so this was where the conflicts were occuring. Simply putting the cursor at the first System library in the solution explorer, cursor down the list and looking for any references to 2.0.0.0, removing and re-adding newer 4.0.0.0 version did the trick.

The strange this was that most of the references had been correctly updated and if it weren't for Crystal reports, I probably would never had noticed...


G
GorvGoyl

Quick Fix:

Right click on solution -> Manage NuGet packages for solution -> Under Consolidate you can see if there are different versions of the same package were installed. Uninstall different versions and install the latest one.


This should be the top answer. Consolidate NuSet for entire Solution allows you to see where the issues are and update them without any problem
This is the most simple answer to this question, thanks for your help.
B
BartoszKP

I made an application based on Mike Hadlow application: AsmSpy.

My app is a WPF app with GUI and can be download from my home webserver: AsmSpyPlus.exe.

Code is available at: GitHub

https://i.stack.imgur.com/K89Zp.png


B
Bhargav Rao

As mentioned here, you need to remove the unused references and the warnings will go.


M
Mike Yinger

ASP.NET build manager is building the website by going through the folders alphabetically, and for each folder it figures out it dependencies and builds the dependencies first and then the selected folder.

In this case the problematic folder which is ~/Controls, is selected to be built at the beginning, from yet an unknown reason, it builds some of the controls there as a separate assembly instead of inside the same assembly as other controls (seems to be connected to the fact that some controls are dependent on other controls in the same folder).

Then the next folder which is built (~/File-Center/Control) is dependent on the root folder ~/ which is dependent on ~/Controls, so the folder ~/Controls is being built again only this time the controls which were separated to their own assembly are now joined to the same assembly as other controls with the separated assembly still being referenced.

So at this point 2 assembly (at least) have the same controls and the build fails.

Although we still don't know why this happened, we were able to work around it by changing the Controls folder name to ZControls, this way it is not built before ~/File-Center/Control, only after and this way it is built as it should.


O
Ohad Schneider

Sometimes AutoGenerateBindingRedirects isn't enough (even with GenerateBindingRedirectsOutputType). Searching for all the There was a conflict entries and fixing them manually one by one can be tedious, so I wrote a small piece of code that parses the log output and generates them for you (dumps to 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);

Tip: use MSBuild Binary and Structured Log Viewer and only generate binding redirects for the conflicts in the project that emits the warning (that is, only past those there was a conflict lines to the input text file for the code above [AssemblyConflicts.txt]).


D
David Gardiner

A simplest way without without one taking into account of (internal) dependencies :

Open "Solution Explorer". Click on "Show all files" Expand "References" You'll see one (or more) reference(s) with slightly different icon than the rest. Typically, it is with yellow box suggesting you to take a note of it. Just remove it. Add the reference back and compile your code. That's all.

In my case, there was a problem with MySQL reference. Somehow, I could list three versions of it under the list of all available references. I followed process 1 through 6 above and it worked for me.


C
Community

Visual Studio for Mac Community addition:

As AMissico's answer requires changing the log level, and neither ASMSpy nor ASMSpyPlus are available as a cross-platform solution, here is a short addition for Visual Studio for Mac:

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

It's in Visual Studio Community → Preferences... → Projects → Build Log → verbosity


P
Pascal Carmoni

If you have resharper, remove all unused reference on your solution.