Memecahkan MSB3247 - Konflik yang ditemukan antara versi yang berbeda dari unit dependen yang sama

427

Solusi .NET 3.5 berakhir dengan peringatan ini saat kompilasi dengan msbuild.

Terkadang NDepend mungkin membantu tetapi dalam kasus ini tidak memberikan rincian lebih lanjut. Seperti Bob, saya akhirnya harus membuka setiap majelis di ILDASM sampai saya menemukan yang merujuk versi yang lebih lama dari majelis dependen.

Saya memang mencoba menggunakan MSBUILD dari VS 2010 Beta 2 (seperti yang ditunjukkan artikel Connect ini diperbaiki dalam versi CLR berikutnya) tetapi itu tidak memberikan rincian lebih lanjut baik (mungkin memperbaiki postingan Beta 2)

Apakah ada pendekatan yang lebih baik (lebih otomatis)?

David Gardiner
sumber
2
Dalam kasus saya, saya hanya harus memastikan semua proyek dalam solusi menjalankan versi nuget yang sama (cukup perbarui semua ke yang terbaru).
Michael

Jawaban:

576

Ubah "proyek MSBuild build verbosity output" menjadi "Detail" atau lebih tinggi. Untuk melakukan ini, ikuti langkah-langkah ini:

  1. Buka dialog Opsi ( Alat -> Opsi ... ).
  2. Di pohon sebelah kiri, pilih simpul Proyek dan Solusi , lalu pilih Bangun dan Jalankan .
    • Catatan: jika simpul ini tidak muncul, pastikan bahwa kotak centang di bagian bawah dialog Tampilkan semua pengaturan dicentang.
  3. Di halaman alat / opsi yang muncul, atur tingkat proyek verbosity output membangun MSBuild ke pengaturan yang sesuai tergantung pada versi Anda:

  4. Bangun proyek dan lihat di jendela output.

Lihat pesan MSBuild. The ResolveAssemblyReferencestugas, yang merupakan tugas dari yang MSB3247 berasal, akan membantu Anda debug isu ini.

Kasus spesifik saya adalah referensi yang salah untuk SqlServerCe. Lihat di bawah. Saya punya dua proyek referensi dua versi SqlServerCe yang berbeda. Saya pergi ke proyek dengan versi yang lebih lama, menghapus referensi, lalu menambahkan referensi yang benar.

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.

Anda tidak harus membuka setiap majelis untuk menentukan versi majelis yang dirujuk.

  • Anda dapat memeriksa Properti dari masing-masing Referensi.
  • Buka properti proyek dan periksa versi bagian Referensi.
  • Buka proyek dengan Editor Teks.
  • Gunakan .Net Reflector.
AMissico
sumber
5
Solusi Anda terlihat bagus bagi saya, namun saya pikir itu tidak selalu berguna untuk menggunakan bagian Referensi untuk melihat nomor versi. Saya sering melihat VS "bohong" kepada saya tentang versi yang digunakan vs. versi mana yang sebenarnya disebutkan dalam file .csproj.
David Gardiner
5
@ David Gardiner - Saya setuju dengan pernyataan "bohong" Anda saat menggunakan proyek C #. Dalam pengalaman saya, proyek C # dapat menjadi bingung mengenai versi yang dirujuk dan versi aktual yang dikompilasi / ditautkan. Ketika ini terjadi, saya membersihkan solusinya, secara manual menghapus folder bin dan obj, kemudian menghapus rakitan proyek sementara di% APPDATA%. Solusi rekondisi biasanya menyelesaikan masalah. (VB jarang menderita masalah khusus ini.)
AMissico
54
menang karena memberi tahu orang-orang untuk benar-benar menggunakan jendela Output. Build jauh lebih dari jendela F5 + Daftar Kesalahan.
JJS
2
Seperti yang disebutkan ErikHeemskerk dalam jawabannya, di Visual Studio 2010 Anda perlu mengatur verbositas output ke detail untuk melihat output dari ResolveAssemblyReferences.
Robin Clowers
12
Petunjuk: untuk menemukan tempat yang tepat dalam output build verbose, salin teks ke dalam editor teks, cari "Ditemukan konflik antara versi berbeda dari rakitan dependen yang sama.".
Contango
133

Mike Hadlow telah memposting aplikasi konsol kecil bernama AsmSpy yang dengan lebih baik mencantumkan referensi setiap rakitan:

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

Ini adalah cara yang jauh lebih cepat untuk sampai ke bagian bawah MSB3247 peringatan, daripada bergantung pada output MSBuild.

Noel Abrahams
sumber
1
AsmSpy luar biasa, Anda hanya perlu ingat bahwa Anda sedang mencari referensi ke DLL pihak ketiga dengan versi yang tidak cocok. Secara umum, versi yang tidak cocok dalam referensi ke perpustakaan standar tidak akan menyebabkan peringatan ini (dan Anda akan melihatnya banyak).
Tod Thomson
Ini adalah alat kecil yang hebat yang membantu saya memecahkan masalah saya segera. Dalam kasus saya, bagaimanapun, itu bukan DLL pihak ketiga, melainkan referensi ke System.Management.Automation.dll yang memiliki referensi berbeda ke mscorlib.dll.
Chris Gillum
Alat ini bagus, namun tidak berfungsi dalam semua keadaan. Setidaknya untuk proyek .NET 4.5 itu tidak menunjukkan versi referensi bertabrakan untuk saya. + msbuild output menamai DLL yang dipermasalahkan dengan paths dan semuanya.
twomm
11
Terima kasih untuk kata-kata baik kalian :)
Mike Hadlow
Anda baru saja menyelamatkan saya beberapa jam kerja! Memang membantu untuk membaca output terperinci, tetapi begitu saya melakukannya, mudah untuk memverifikasi kembali dengan alat Anda.
Norman H
22

Kadang-kadang jawaban @ AMissico tidak cukup. Dalam kasus saya, saya tidak dapat menemukan kesalahan di jendela Output jadi saya memutuskan untuk membuat file log dan menganalisisnya, dengan melakukan langkah-langkah berikut:

  1. Menyimpan build log ke file ... https://msdn.microsoft.com/en-us/library/ms171470.aspx

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

  2. Temukan teks: warning MS...atau info peringatan spesifik: (mis. Baris 9293) Found conflicts between different versions...dan detail lengkap kesalahan konflik akan berada di atas pesan ini (mis. Baris 9277)There was a conflicts between... Temukan pesan kesalahan

Visual Studio 2013

Jaider
sumber
Petunjuk bagus untuk mencari 3277 di output.
sfuqua
21

Saya menemukan bahwa (setidaknya dalam Visual Studio 2010) Anda perlu mengatur verbositas output ke setidaknya Detail untuk dapat menemukan masalah.

Mungkin masalah saya adalah referensi yang sebelumnya merupakan referensi GAC, tapi itu tidak lagi terjadi setelah mesin saya instal ulang.

ErikHeemskerk
sumber
1
Pergi ke Alat-> Pilihan-> Proyek dan Solusi-> Bangun dan Jalankan untuk mengatur verbositas keluaran.
Farshid
8

Saya memiliki kesalahan yang sama dan tidak bisa mengatasinya dengan jawaban yang lain. Saya menemukan bahwa kita dapat "Mengkonsolidasikan" paket NuGet.

  1. Klik kanan pada solusinya
  2. Klik Kelola Paket Nuget
  3. Konsolidasi tab dan perbarui ke versi yang sama.
Carol
sumber
7

Peringatan ini dihasilkan untuk standar ASP.NET MVC 4 beta lihat di sini

Di, semua pemeran Peringatan ini dapat dihilangkan dengan mengedit secara manual file .csproj untuk proyek Anda.

modifikasi ........: Referensi Sertakan = "System.Net.Http"

untuk membaca ......: Referensi Sertakan = "System.Net.Http, Versi = 4.0.0.0"

RouR
sumber
1
Saya mengikuti ini dan kesalahan telah hilang. Masih tidak tahu bagaimana atau mengapa, saya memulai proyek MVC 4 dengan VS2010 kemudian bermigrasi ke VS2012. Namun, menambahkan atribut versi, membuat kesalahan hilang. Terima kasih
MaiOM
6

Gunakan pembaca ketergantungan

Dengan menggunakan dep.exe Anda dapat mencantumkan semua dependensi bersarang dari seluruh folder. Dikombinasikan dengan alat unix seperti grep atau awk, ini dapat membantu Anda untuk menyelesaikan masalah Anda

Menemukan majelis yang dirujuk dalam lebih dari satu versi

$ 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            

Baris perintah yang tidak jelas ini menjalankan dep.exe kemudian mengirimkan output dua kali ke awk

  • letakkan orang tua dan anak dalam satu kolom (secara default setiap baris berisi satu orang tua dan anak untuk mengungkapkan fakta bahwa orang tua ini bergantung pada anak itu)
  • kemudian lakukan semacam 'grup dengan' menggunakan array asosiatif

Memahami bagaimana perakitan ini ditarik ke tempat sampah Anda

$ 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 

Dalam contoh ini, alat ini akan menunjukkan kepada Anda bahwa System.Web.Http 5.2.3 berasal dari ketergantungan Anda ke FooLib sedangkan versi 4.0.0 berasal dari BarLib.

Maka Anda memiliki pilihan di antara

  • meyakinkan pemilik lib untuk menggunakan versi yang sama
  • berhenti menggunakan mereka
  • menambahkan pengalihan yang mengikat dalam file konfigurasi Anda untuk menggunakan versi terbaru

Cara menjalankan hal ini di Windows

Jika Anda tidak memiliki shell tipe unix, Anda harus mengunduhnya sebelum dapat menjalankan awkdan grep. Coba salah satu dari yang berikut ini

Manitra Andriamitondra
sumber
4

Saya punya masalah ini juga dan menggunakan saran AMissico juga menemukan masalah (Meskipun harus mengatur tingkat verbosity ke Detail.

Masalahnya sebenarnya cukup lurus ke depan meskipun setelah menemukan pelakunya.

Latar Belakang: Saya memutakhirkan proyek saya dari VS2008 ke VS2010. Dalam VS2008 kerangka kerja target adalah 3,5 dan ketika saya membawanya ke VS2010 saya mengubahnya menjadi 4 (Penuh). Saya juga memutakhirkan beberapa komponen pihak ketiga termasuk laporan Crystal.

Ternyata sebagian besar referensi Sistem di mana menunjuk pada versi 4.0.0.0 tetapi pasangan belum secara otomatis berubah (Sistem dan System.Web. Layanan) dan masih melihat 2.0.0.0. Laporan Crystal merujuk pada 4.0.0.0 dan di sinilah konflik terjadi. Cukup dengan meletakkan kursor di pustaka sistem pertama di explorer solusi, kursor ke bawah daftar dan mencari referensi ke 2.0.0.0, menghapus dan menambahkan kembali versi 4.0.0.0 yang lebih baru melakukan trik.

Yang aneh adalah bahwa sebagian besar referensi telah diperbarui dengan benar dan jika bukan karena laporan Crystal, saya mungkin tidak akan pernah memperhatikan ...

Hamiora
sumber
2

Seperti yang disebutkan di sini , Anda perlu menghapus referensi yang tidak digunakan dan peringatan akan pergi.

lex87
sumber
1

ASP.NET build manager membangun situs web dengan menelusuri folder-folder secara alfabet, dan untuk setiap folder, ia menentukan dependensi dan membangun dependensi terlebih dahulu, kemudian folder yang dipilih.

Dalam hal ini folder yang bermasalah yaitu ~ / Kontrol, dipilih untuk dibangun di awal, dari alasan yang belum diketahui, ia membangun beberapa kontrol di sana sebagai rakitan terpisah alih-alih di dalam rakitan yang sama dengan kontrol lainnya (tampaknya terhubung ke fakta bahwa beberapa kontrol tergantung pada kontrol lain di folder yang sama).

Kemudian folder berikutnya yang dibangun (~ / File-Center / Control) tergantung pada folder root ~ / yang bergantung pada ~ / Kontrol, sehingga folder ~ / Kontrol sedang dibangun lagi hanya kali ini kontrol yang dipisahkan ke rakitan mereka sendiri sekarang bergabung dengan rakitan yang sama dengan kontrol lain dengan rakitan yang terpisah masih dirujuk.

Jadi pada titik ini, rakitan 2 (setidaknya) memiliki kontrol yang sama dan build gagal.

Meskipun kami masih tidak tahu mengapa ini terjadi, kami dapat mengatasinya dengan mengubah nama folder Kontrol menjadi ZControls, cara ini tidak dibangun sebelum ~ / File-Center / Control, hanya setelah dan dengan cara ini dibangun seperti seharusnya.

Mike Yinger
sumber
1

Perbaikan Cepat:

Klik kanan pada solusi -> Kelola paket NuGet untuk solusi -> Di bawah Konsolidasi Anda dapat melihat apakah ada versi berbeda dari paket yang sama diinstal. Copot versi yang berbeda dan instal versi terbaru.

JerryGoyal
sumber
1

Terkadang AutoGenerateBindingRedirectstidak cukup (bahkan dengan GenerateBindingRedirectsOutputType). Mencari semua There was a conflictentri dan memperbaikinya secara manual satu per satu bisa membosankan, jadi saya menulis sepotong kecil kode yang mem-parsing keluaran log dan menghasilkannya untuk Anda (sesuai dengan 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: gunakan MSBuild Binary dan Structured Log Viewer dan hanya menghasilkan pengalihan yang mengikat untuk konflik dalam proyek yang memancarkan peringatan (yaitu, hanya melewati there was a conflictbaris tersebut ke file teks input untuk kode di atas [ AssemblyConflicts.txt]).

Ohad Schneider
sumber
0

Cara paling sederhana tanpa tanpa memperhitungkan ketergantungan (internal):

  1. Buka "Solution Explorer".
  2. Klik pada "Tampilkan semua file"
  3. Luaskan "Referensi"
  4. Anda akan melihat satu (atau lebih) referensi dengan ikon yang sedikit berbeda dari yang lain. Biasanya, ini dengan kotak kuning menyarankan Anda untuk mencatatnya. Hapus saja.
  5. Tambahkan referensi kembali dan kompilasi kode Anda.
  6. Itu saja.

Dalam kasus saya, ada masalah dengan referensi MySQL. Entah bagaimana, saya bisa mendaftar tiga versi di bawah daftar semua referensi yang tersedia. Saya mengikuti proses 1 hingga 6 di atas dan itu berhasil untuk saya.

Sukhi
sumber
0

Jika Anda memiliki resharper, hapus semua referensi yang tidak digunakan pada solusi Anda.

Pascal Carmoni
sumber