Risoluzione di MSB3247: rilevati conflitti tra diverse versioni dello stesso assembly dipendente

StackOverflow https://stackoverflow.com/questions/1871073

  •  18-09-2019
  •  | 
  •  

Domanda

Una soluzione .NET 3.5 si è conclusa con questo avviso durante la compilazione con msbuild.

A volte NDepend potrebbe aiutare ma in questo caso non ha fornito ulteriori dettagli. Come Bob Alla fine ho dovuto ricorrere all'apertura di ciascun assembly in ILDASM finché non ho trovato quello che faceva riferimento a una versione precedente dell'assembly dipendente.

Ho provato a utilizzare MSBUILD da VS 2010 Beta 2 (poiché l'articolo di Connect indicava che questo problema era stato risolto nella versione successiva di CLR) ma neanche questo ha fornito ulteriori dettagli (forse è stato risolto dopo la Beta 2)

Esiste un approccio migliore (più automatizzato)?

È stato utile?

Soluzione

Modificare la "verbosità dell'output della build del progetto MSBuild" in "Dettagliato" o superiore.Per fare ciò, attenersi alla seguente procedura:

  1. Visualizza la finestra di dialogo Opzioni (Strumenti -> Opzioni...).
  2. Nell'albero a sinistra, seleziona il Progetti e Soluzioni nodo, quindi selezionare Costruisci ed esegui.
    • Nota:se questo nodo non viene visualizzato, assicurati che la casella di controllo nella parte inferiore della finestra di dialogo Mostra tutte le impostazioni è controllato.
  3. Nella pagina strumenti/opzioni visualizzata, imposta il file Il progetto MSBuild crea la verbosità dell'output livello all'impostazione appropriata a seconda della versione:

  4. Costruisci il progetto e guarda nella finestra di output.

Controlla i messaggi di MSBuild.IL ResolveAssemblyReferences task, che è l'attività da cui ha origine MSB3247, dovrebbe aiutarti a eseguire il debug di questo particolare problema.

Il mio caso specifico era un riferimento errato a SqlServerCe.Vedi sotto.Avevo due progetti che facevano riferimento a due diverse versioni di SqlServerCe.Sono andato al progetto con la versione precedente, ho rimosso il riferimento, quindi ho aggiunto il riferimento corretto.

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.

Non è necessario aprire ciascun assembly per determinare le versioni degli assembly a cui si fa riferimento.

  • È possibile controllare le proprietà di ciascun riferimento.
  • Apri le proprietà del progetto e controlla le versioni della sezione Riferimenti.
  • Apri i progetti con un editor di testo.
  • Utilizza .Net Reflector.

Altri suggerimenti

Mike Hadlow ha postato una piccola applicazione console denominata AsmSpy che piuttosto bene elenca i riferimenti di ogni montaggio:

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

Questo è un modo molto più veloce per andare a fondo della MSB3247 avvertimento, oltre a dipendere dalla uscita MSBuild.

A volte @AMissico risposta non è sufficiente. Nel mio caso, non riuscivo a trovare l'errore nelle finestre di uscita così ho deciso di creare un file di log e analizzarlo, effettuando le seguenti operazioni:

  1. Il salvataggio del log di compilazione in un file ... https: / /msdn.microsoft.com/en-us/library/ms171470.aspx

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

  2. Trova il testo: warning MS... o la specifica informazioni ATTENZIONE (linea per esempio 9293) Found conflicts between different versions... e il dettaglio completo della errore di conflitto sarà al di sopra di questo messaggio (ad esempio, la linea 9277) There was a conflicts between... Trovare il messaggio di errore

Visual Studio 2013

ho scoperto che (almeno in Visual Studio 2010) è necessario impostare la verbosità di uscita ad almeno dettagliata per essere in grado di individuare il problema.

Potrebbe essere che il mio problema era un punto di riferimento che in precedenza era un riferimento GAC, ma che non era più il caso dopo reinstallazione della mia macchina.

generato Questo avviso per impostazione predefinita ASP.NET MVC 4 beta vedi qui

  

In qualsiasi getto Questo avviso può essere eliminato modificando manualmente il   Csproj file per il vostro progetto.

     

modificare ........: Riferimento include = "System.Net.Http"

     

per leggere ......: Riferimento include = "System.Net.Http, Version = 4.0.0.0"

ho avuto lo stesso errore e non sono riuscito a capirlo con le altre risposte. Ho scoperto che siamo in grado di "Consolida" pacchetti Nuget.

  1. Fare clic destro sulla soluzione
  2. Fare clic su Gestione pacchetti Nuget
  3. scheda e l'aggiornamento alla stessa versione Consolida.

, utilizzare un lettore di dipendenza

dep.exe è possibile elencare tutte le dipendenze nidificate di un'intera cartella. In combinazione con strumenti Unix come grep o awk, può aiutare a risolvere il problema

assemblee Trovare cui viene fatto riferimento in più di una versione

$ 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            

Questa riga di comando oscuro corre dep.exe poi i tubi l'uscita due volte per awk per

  • mettere il genitore e figlio in una singola colonna (per impostazione predefinita ogni riga contiene un genitore e un bambino di esprimere il fatto che questo genitore dipende di quel bambino)
  • quindi effettuare una sorta di 'gruppo da' utilizzando un array associativo

Capire come questa assemblea sono tirato nel bidone

$ 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 questo esempio, lo strumento avrebbe mostrato che System.Web.Http 5.2.3 viene dal vostro dipendenza FooLib mentre la versione 4.0.0 viene da BarLib.

Poi si ha la possibilità di scegliere tra

  • convincere i proprietari delle librerie per utilizzare la stessa versione
  • smettere di usare uno di loro
  • l'aggiunta di reindirizzamento vincolanti nel file di configurazione per utilizzare la versione più recente

Come eseguire queste cose in Windows

Se non si dispone di un tipo di shell UNIX è necessario scaricare uno prima di essere in grado di eseguire awk grepand. Provare una delle seguenti

Ho avuto anche questo problema e ho usato il consiglio di AMissico anche scoprire il problema (anche se ha dovuto impostare livello di verbosità di dettagliata.

Il problema era in realtà abbastanza semplice anche se dopo aver trovato il colpevole.

Sfondo: Ho aggiornato il mio progetto da VS2008 a VS2010. In VS2008 quadro obiettivo era 3.5 e quando ho portato in VS2010 sono passato a 4 (Full). Ho anche aggiornato alcuni componenti di terze parti, tra cui i report Crystal.

Si è scoperto la maggior parte dei riferimenti di sistema in cui puntando alla versione 4.0.0.0, ma una coppia non era stata cambiata automaticamente (Sistema e System.Web.Services) ed erano ancora guardando 2.0.0.0. report Crystal fa riferimento 4.0.0.0 e quindi questo era il luogo dove i conflitti sono stati in corso. Basta mettere il cursore alla prima libreria del sistema nella soluzione esploratore, il cursore verso il basso la lista e alla ricerca di qualsiasi riferimento a 2.0.0.0, la rimozione e ri-aggiungendo più recente versione 4.0.0.0 ha fatto il trucco.

Lo strano questo era che la maggior parte dei riferimenti era stato correttamente aggiornato e, se non fosse per i report Crystal, probabilmente avrei mai notato ...

Ho fatto una domanda basata su applicazione Mike Hadlow: AsmSpy .

La mia app è un applicazione WPF con interfaccia grafica e può essere scaricato da casa mia webserver: AsmSpyPlus. exe .

Codice è disponibile all'indirizzo: GitHub

Gui campione

Come accennato qui , è necessario rimuovere i riferimenti non utilizzati e le avvertenze andrà.

ASP.NET accumulo responsabile è la costruzione del sito passando attraverso le cartelle in ordine alfabetico, e per ogni cartella si capisce che le dipendenze e costruisce le dipendenze e poi la cartella selezionata.

In questo caso la cartella problematica che è ~ / Controlli, viene selezionato per essere costruita agli inizi, da ancora un motivo sconosciuto, costruisce alcuni dei controlli lì come un assembly separato invece che all'interno della stessa assemblea di altri controlli (sembra essere legato al fatto che alcuni controlli dipendono da altri controlli nella stessa cartella).

Poi la cartella successiva che è costruito (~ / file-Center / Control) dipende dalla cartella principale ~ / che dipende ~ / Controlli, quindi la cartella ~ / Controlli si sta costruendo di nuovo solo che questa volta i controlli che sono stati separati al loro assemblaggio sono ora unite stesso assieme ad altri controlli con il gruppo separato ancora riferimento.

Quindi a questo punto di montaggio 2 (almeno) hanno gli stessi controlli e la compilazione fallisce.

Anche se ancora non sappiamo il motivo per cui questo è accaduto, siamo stati in grado di lavorare intorno ad esso, cambiando il nome della cartella di controlli al ZControls, in questo modo non è stato costruito prima del ~ / File-Center / controllo, solo dopo e in questo modo è costruito come dovrebbe.

Quick Fix:

Fare clic destro sulla soluzione -> Gestisci pacchetti Nuget per soluzione -> In Consolida si può vedere se ci sono diverse versioni dello stesso pacchetto sono stati installati. Disinstallare le versioni differenti ed installare quello più recente.

A volte non è sufficiente AutoGenerateBindingRedirects (anche con GenerateBindingRedirectsOutputType ). Ricerca di tutte le voci There was a conflict e fissandoli manualmente uno per uno può essere noioso, così ho scritto un piccolo pezzo di codice che analizza l'output del registro e li genera per voi (discariche a 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);

Suggerimento: utilizzare MSBuild binario e strutturato Log Viewer e solo generare redirect vincolanti per i conflitti nel progetto che emette l'avviso (vale a dire, solo il passato quelle linee there was a conflict al file di testo di input per il codice di cui sopra [AssemblyConflicts.txt]).

Un modo più semplice, senza senza uno tener conto delle dipendenze (interni):

  1. Apri "Solution Explorer".
  2. Fare clic su "Mostra tutti i file"
  3. Espandi "Riferimenti"
  4. Vedrai uno (o più) di riferimento (s) con l'icona un po 'diverso rispetto al resto. In genere, è con la scatola gialla che suggerisce di prendere nota di esso. Basta rimuoverlo.
  5. Aggiungi il riferimento indietro e compilare il codice.
  6. Questo è tutto.

Nel mio caso, c'era un problema con riferimento MySQL. In qualche modo, potrei elencare tre versioni di esso sotto l'elenco di tutti i riferimenti disponibili. Ho seguito processo da 1 a 6 di cui sopra e ha funzionato per me.

Visual Studio per l'aggiunta Mac Community:

AMissico risposta richiede la modifica del livello di registrazione, e né ASMSpy né ASMSpyPlus sono disponibili come soluzione cross-platform, ecco un breve aggiunta per Visual Studio per Mac:

  

https://docs.microsoft.com/en -us / VisualStudio / mac / compilazione-e-building

E 'in di Visual Studio Comunità → Preferenze ... → Progetti → costruire Registro → verbosità

Se avete ReSharper, rimuovere ogni riferimento inutilizzato sul soluzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top