MSB3247 lösen - Es wurden Konflikte zwischen verschiedenen Versionen derselben abhängigen Assembly gefunden

427

Eine .NET 3.5-Lösung hat diese Warnung beim Kompilieren mit msbuild erhalten.

Manchmal könnte NDepend helfen, aber in diesem Fall gab es keine weiteren Details. Wie Bob musste ich schließlich jede Assembly in ILDASM öffnen, bis ich die fand, die auf eine ältere Version der abhängigen Assembly verweist.

Ich habe versucht, MSBUILD aus VS 2010 Beta 2 zu verwenden (wie im Connect-Artikel angegeben, wurde dies in der nächsten Version der CLR behoben), aber das lieferte auch keine weiteren Details (möglicherweise nach Beta 2 behoben).

Gibt es einen besseren (automatisierteren) Ansatz?

David Gardiner
quelle
2
In meinem Fall musste ich nur sicherstellen, dass auf allen Projekten in der Lösung dieselbe Version von Nuget-Paketen ausgeführt wurde (kann einfach alle auf den neuesten Stand bringen).
Michael

Antworten:

576

Ändern Sie die Ausführlichkeit der Ausgabe des MSBuild-Projektbuilds in "Detailliert" oder höher. Gehen Sie dazu folgendermaßen vor:

  1. Rufen Sie das Dialogfeld Optionen auf ( Extras -> Optionen ... ).
  2. Wählen Sie in der linken Baumstruktur den Knoten Projekte und Lösungen aus , und wählen Sie dann Erstellen und Ausführen aus .
    • Hinweis: Wenn dieser Knoten nicht angezeigt wird, stellen Sie sicher, dass das Kontrollkästchen am unteren Rand des Dialogfelds Alle Einstellungen anzeigen aktiviert ist.
  3. Stellen Sie auf der angezeigten Seite Tools / Optionen die Ausführlichkeitsstufe für die Ausgabe der MSBuild-Projekterstellung abhängig von Ihrer Version auf die entsprechende Einstellung ein:

  4. Erstellen Sie das Projekt und schauen Sie in das Ausgabefenster.

Überprüfen Sie die MSBuild-Nachrichten. Die ResolveAssemblyReferencesAufgabe, von der MSB3247 stammt, soll Ihnen beim Debuggen dieses speziellen Problems helfen.

Mein spezieller Fall war ein falscher Verweis auf SqlServerCe. Siehe unten. Ich hatte zwei Projekte, die auf zwei verschiedene Versionen von SqlServerCe verweisen. Ich ging mit der älteren Version zum Projekt, entfernte die Referenz und fügte dann die richtige Referenz hinzu.

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.

Sie müssen nicht jede Assembly öffnen, um die Versionen der Assemblys zu ermitteln, auf die verwiesen wird.

  • Sie können die Eigenschaften jeder Referenz überprüfen.
  • Öffnen Sie die Projekteigenschaften und überprüfen Sie die Versionen des Abschnitts Referenzen.
  • Öffnen Sie die Projekte mit einem Texteditor.
  • Verwenden Sie .Net Reflector.
AMissico
quelle
5
Ihre Lösungen sehen für mich gut aus, aber ich denke nicht, dass es immer nützlich ist, den Abschnitt Referenzen zum Anzeigen von Versionsnummern zu verwenden. Ich habe oft gesehen, wie VS mich "angelogen" hat, welche Version es verwendet und welche Version tatsächlich in der .csproj-Datei erwähnt wird.
David Gardiner
5
@ David Gardiner - Ich würde Ihrer "Lügen" -Aussage bei der Verwendung von C # -Projekten zustimmen. Nach meiner Erfahrung können C # -Projekte hinsichtlich der referenzierten Version und der tatsächlich kompilierten / verknüpften Version verwirrt werden. In diesem Fall bereinige ich die Lösung, lösche manuell die Ordner bin und obj und lösche dann die temporären Projektassemblys in% APPDATA%. Eine Neuerstellungslösung löst normalerweise das Problem. (VB leidet selten unter diesem spezifischen Problem.)
AMissico
54
gewinnen Sie, wenn Sie den Leuten sagen, dass sie das Ausgabefenster tatsächlich verwenden sollen. Build ist so viel mehr als das Fenster F5 + Fehlerliste.
JJS
2
Wie ErikHeemskerk in seiner Antwort erwähnt hat, müssen Sie in Visual Studio 2010 die Ausführlichkeit der Ausgabe auf detailliert einstellen, um die Ausgabe von ResolveAssemblyReferences anzuzeigen.
Robin Clowers
12
Tipp: Um die genaue Stelle in der ausführlichen Build-Ausgabe zu finden, kopieren Sie den Text in einen Texteditor und suchen Sie nach "Gefundene Konflikte zwischen verschiedenen Versionen derselben abhängigen Assembly".
Contango
133

Mike Hadlow hat eine kleine Konsolen-App namens AsmSpy veröffentlicht , in der die Referenzen der einzelnen Assemblys ziemlich gut aufgelistet sind:

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

Dies ist ein viel schnellerer Weg, um der Warnung MSB3247 auf den Grund zu gehen, als von der MSBuild-Ausgabe abhängig zu sein.

Noel Abrahams
quelle
1
AsmSpy ist fantastisch. Sie müssen sich nur daran erinnern, dass Sie nach Verweisen auf DLLs von Drittanbietern mit nicht übereinstimmenden Versionen suchen. Im Allgemeinen verursachen nicht übereinstimmende Versionen in Verweisen auf die Standardbibliotheken diese Warnungen nicht (und Sie werden sie häufig sehen).
Tod Thomson
Dies ist ein großartiges kleines Tool, mit dem ich mein Problem sofort lösen konnte. In meinem Fall waren es jedoch nicht genau DLLs von Drittanbietern, sondern Verweise auf System.Management.Automation.dll, die unterschiedliche Verweise auf mscorlib.dll hatten.
Chris Gillum
Das Tool ist nett, funktioniert jedoch nicht unter allen Umständen. Zumindest für ein .NET 4.5-Projekt wurden die kollidierenden Referenzversionen für mich nicht angezeigt. + msbuild output benennt die fraglichen DLLs mit Pfaden und allen.
Zwei
11
Vielen Dank für die freundlichen Worte Jungs :)
Mike Hadlow
Sie haben mir gerade einige Stunden Arbeit erspart! Es hat zwar geholfen, die detaillierte Ausgabe durchzulesen, aber als ich das getan habe, war es einfach, sie erneut mit Ihrem Tool zu überprüfen.
Norman H
22

Manchmal reicht die Antwort von @AMissico nicht aus. In meinem Fall konnte ich den Fehler in den Ausgabefenstern nicht finden. Daher habe ich beschlossen, eine Protokolldatei zu erstellen und diese zu analysieren, indem ich die folgenden Schritte ausführte:

  1. Speichern des Build-Protokolls in einer Datei ... https://msdn.microsoft.com/en-us/library/ms171470.aspx

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

  2. Suchen Sie den Text: warning MS...oder die spezifischen Warninformationen: (z. B. Zeile 9293) Found conflicts between different versions...und das vollständige Detail des Konfliktfehlers befindet sich über dieser Nachricht (z. B. Zeile 9277).There was a conflicts between... Suchen Sie die Fehlermeldung

Visual Studio 2013

Jaider
quelle
Toller Hinweis, um in der Ausgabe nach 3277 zu suchen.
Sfuqua
21

Ich habe festgestellt, dass Sie (zumindest in Visual Studio 2010) die Ausführlichkeit der Ausgabe auf mindestens Detailliert setzen müssen, um das Problem erkennen zu können.

Möglicherweise war mein Problem eine Referenz, die zuvor eine GAC-Referenz war, aber nach der Neuinstallation meines Computers war dies nicht mehr der Fall.

ErikHeemskerk
quelle
1
Gehen Sie zu Extras-> Optionen-> Projekte und Lösungen-> Erstellen und Ausführen, um die Ausführlichkeit der Ausgabe festzulegen.
Farshid
8

Ich hatte den gleichen Fehler und konnte ihn mit den anderen Antworten nicht herausfinden. Ich habe festgestellt, dass wir NuGet-Pakete "konsolidieren" können.

  1. Klicken Sie mit der rechten Maustaste auf die Lösung
  2. Klicken Sie auf Nuget-Pakete verwalten
  3. Registerkarte konsolidieren und auf dieselbe Version aktualisieren.
Carol
quelle
7

Diese Warnung, die für die Standard-Betaversion von ASP.NET MVC 4 generiert wurde, finden Sie hier

In jeder Besetzung dieser Warnung kann durch manuelles Bearbeiten der .csproj-Datei für Ihr Projekt beseitigt werden.

Ändern ........: Referenz Include = "System.Net.Http"

zu lesen ......: Referenz Include = "System.Net.Http, Version = 4.0.0.0"

RouR
quelle
1
Ich bin dem gefolgt und der Fehler ist verschwunden. Ich weiß immer noch nicht wie oder warum, ich habe ein MVC 4-Projekt mit VS2010 gestartet und dann auf VS2012 migriert. Durch Hinzufügen des Versionsattributs wurde der Fehler jedoch ausgeblendet. Vielen Dank
MaiOM
6

Verwenden Sie einen Abhängigkeitsleser

Mit dep.exe können Sie alle verschachtelten Abhängigkeiten eines gesamten Ordners auflisten . In Kombination mit Unix-Tools wie grep oder awk können Sie Ihr Problem lösen

Suchen von Assemblys, auf die in mehr als einer Version verwiesen wird

$ 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            

Diese obskure Befehlszeile führt dep.exe aus und leitet die Ausgabe dann zweimal an awk weiter

  • Setzen Sie das Elternteil und das Kind in eine einzelne Spalte (standardmäßig enthält jede Zeile ein Elternteil und ein Kind, um die Tatsache auszudrücken, dass dieses Elternteil von diesem Kind abhängt).
  • Führen Sie dann eine Art 'Gruppieren nach' mithilfe eines assoziativen Arrays durch

Verstehen, wie diese Baugruppe in Ihren Papierkorb gezogen wurde

$ 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 diesem Beispiel zeigt Ihnen das Tool, dass System.Web.Http 5.2.3 von Ihrer Abhängigkeit zu FooLib stammt, während die Version 4.0.0 von BarLib stammt.

Dann haben Sie die Wahl zwischen

  • die Besitzer der Bibliotheken davon zu überzeugen, dieselbe Version zu verwenden
  • Hör auf, sie zu benutzen
  • Hinzufügen von Bindungsumleitungen zu Ihrer Konfigurationsdatei, um die neueste Version zu verwenden

Wie man diese Sache in Windows ausführt

Wenn Sie nicht über einen Unix - Shell - Typen haben müssen eine herunterladen , bevor die Lage zu laufen awkund grep. Versuchen Sie eine der folgenden Möglichkeiten

Manitra Andriamitondra
quelle
4

Ich hatte auch dieses Problem und benutzte AMissicos Rat, um das Problem zu entdecken (obwohl ich die Ausführlichkeitsstufe auf Detailliert setzen musste.

Das Problem war jedoch ziemlich einfach, nachdem der Täter gefunden worden war.

Hintergrund: Ich habe mein Projekt von VS2008 auf VS2010 aktualisiert. In VS2008 war das Ziel-Framework 3.5 und als ich es in VS2010 brachte, habe ich es auf 4 (Voll) umgestellt. Ich habe auch einige Komponenten von Drittanbietern aktualisiert, einschließlich Crystal Reports.

Es stellte sich heraus, dass die meisten Systemreferenzen auf Version 4.0.0.0 verweisen, einige jedoch nicht automatisch geändert wurden (System und System.Web.Services) und sich weiterhin mit 2.0.0.0 befassten. Crystal Reports verweist auf 4.0.0.0, und hier traten die Konflikte auf. Setzen Sie einfach den Cursor auf die erste Systembibliothek im Lösungs-Explorer, bewegen Sie den Cursor in der Liste nach unten und suchen Sie nach Verweisen auf 2.0.0.0. Entfernen Sie die neuere Version 4.0.0.0 und fügen Sie sie erneut hinzu.

Das Seltsame war, dass die meisten Referenzen korrekt aktualisiert wurden und ohne Crystal-Berichte hätte ich es wahrscheinlich nie bemerkt ...

Hamiora
quelle
2

Wie hier erwähnt , müssen Sie die nicht verwendeten Referenzen entfernen, und die Warnungen werden gelöscht.

lex87
quelle
1

ASP.NET Build Manager erstellt die Website, indem die Ordner alphabetisch durchsucht werden. Für jeden Ordner werden die Abhängigkeiten ermittelt und zuerst die Abhängigkeiten und dann der ausgewählte Ordner erstellt.

In diesem Fall wird der problematische Ordner ~ / Controls ausgewählt, um zu Beginn erstellt zu werden. Aus einem noch unbekannten Grund werden einige der Steuerelemente dort als separate Assembly erstellt, anstatt in derselben Assembly wie andere Steuerelemente (scheint dies zu tun) mit der Tatsache verbunden sein, dass einige Steuerelemente von anderen Steuerelementen im selben Ordner abhängig sind).

Dann ist der nächste Ordner, der erstellt wird (~ / File-Center / Control), abhängig vom Stammordner ~ /, der von ~ / Controls abhängig ist, sodass der Ordner ~ / Controls nur dieses Mal neu erstellt wird, wenn die Steuerelemente getrennt wurden zu ihrer eigenen Assembly werden jetzt mit derselben Assembly wie andere Steuerelemente verbunden, wobei auf die getrennte Assembly noch verwiesen wird.

Zu diesem Zeitpunkt haben 2 Assemblys (zumindest) dieselben Steuerelemente und der Build schlägt fehl.

Obwohl wir immer noch nicht wissen, warum dies passiert ist, konnten wir es umgehen, indem wir den Namen des Controls-Ordners in ZControls änderten. Auf diese Weise wird er nicht vor ~ / File-Center / Control erstellt, sondern erst nach und auf diese Weise so wie es sollte.

Mike Yinger
quelle
1

Schnelle Lösung:

Klicken Sie mit der rechten Maustaste auf Lösung -> NuGet-Pakete für Lösung verwalten -> Unter Konsolidieren können Sie sehen, ob verschiedene Versionen desselben Pakets installiert wurden. Deinstallieren Sie verschiedene Versionen und installieren Sie die neueste.

JerryGoyal
quelle
1

Manchmal reicht AutoGenerateBindingRedirectses nicht (auch nicht mit GenerateBindingRedirectsOutputType). Das Suchen nach allen There was a conflictEinträgen und das manuelle Korrigieren nacheinander kann mühsam sein. Deshalb habe ich einen kleinen Code geschrieben, der die Protokollausgabe analysiert und für Sie generiert (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);

Tipp: Verwenden Sie MSBuild Binary und Structured Log Viewer und generieren Sie nur verbindliche Weiterleitungen für die Konflikte in dem Projekt, das die Warnung ausgibt (dh nur nach diesen there was a conflictZeilen in die Eingabetextdatei für den obigen Code [ AssemblyConflicts.txt]).

Ohad Schneider
quelle
0

Ein einfachster Weg ohne Berücksichtigung (interner) Abhängigkeiten:

  1. Öffnen Sie den "Projektmappen-Explorer".
  2. Klicken Sie auf "Alle Dateien anzeigen"
  3. Erweitern Sie "Referenzen"
  4. Sie sehen eine (oder mehrere) Referenz (en) mit einem etwas anderen Symbol als die anderen. In der Regel wird ein gelbes Kästchen angezeigt, in dem Sie aufgefordert werden, dies zu notieren. Entfernen Sie es einfach.
  5. Fügen Sie die Referenz zurück und kompilieren Sie Ihren Code.
  6. Das ist alles.

In meinem Fall gab es ein Problem mit der MySQL-Referenz. Irgendwie könnte ich drei Versionen davon unter der Liste aller verfügbaren Referenzen auflisten. Ich habe die obigen Prozesse 1 bis 6 befolgt und es hat bei mir funktioniert.

Sukhi
quelle
0

Wenn Sie einen Resharper haben, entfernen Sie alle nicht verwendeten Verweise auf Ihrer Lösung.

Pascal Carmoni
quelle