Giải quyết MSB3247 - Đã tìm thấy xung đột giữa các phiên bản khác nhau của cùng một tổ hợp phụ thuộc


427

Một .NET 3.5 giải pháp kết thúc với cảnh báo này khi biên dịch với msbuild.

Đôi khi NDepend có thể giúp đỡ, nhưng trong trường hợp này nó không cho biết thêm bất kỳ chi tiết. Giống như Bob tôi đã kết thúc phải nghỉ mát để mở từng lắp ráp trong ILDASM cho đến khi tôi tìm thấy một trong đó đã tham khảo một phiên bản cũ của lắp ráp phụ thuộc.

Tôi đã thử sử dụng MSBUILD từ VS 2010 Beta 2 (vì bài viết Connect cho biết điều này đã được sửa trong phiên bản tiếp theo của CLR) nhưng điều đó cũng không cung cấp thêm chi tiết nào (có thể là bản sửa lỗi Beta 2)

Có một cách tiếp cận (tự động trở lên) tốt hơn?


2
Trong trường hợp của tôi, tôi chỉ cần đảm bảo tất cả các dự án trong giải pháp đang chạy cùng một phiên bản gói nuget (có thể chỉ cần cập nhật tất cả lên bản mới nhất).
Michael

Câu trả lời:


576

Thay đổi "Độ dài đầu ra của dự án xây dựng dự án MSBuild" thành "Chi tiết" hoặc cao hơn. Để làm điều này, hãy làm theo các bước sau:

  1. Đưa ra hộp thoại Tùy chọn ( Công cụ -> Tùy chọn ... ).
  2. Trong cây bên trái, chọn nút Dự án và Giải pháp , sau đó chọn Xây dựng và Chạy .
    • Lưu ý: nếu nút này không hiển thị, hãy đảm bảo rằng hộp kiểm ở cuối hộp thoại Hiển thị tất cả các cài đặt được chọn.
  3. Trong trang công cụ / tùy chọn xuất hiện, đặt mức độ chi tiết đầu ra của dự án xây dựng dự án MSBuild thành cài đặt phù hợp tùy thuộc vào phiên bản của bạn:

  4. Xây dựng dự án và tìm trong cửa sổ đầu ra.

Kiểm tra các thông điệp MSBuild. Các ResolveAssemblyReferencesnhiệm vụ, đó là nhiệm vụ mà từ đó bắt nguồn MSB3247, sẽ giúp bạn gỡ rối vấn đề cụ thể này.

Trường hợp cụ thể của tôi là một tham chiếu không chính xác đến SqlServerCe. Xem bên dưới. Tôi đã có hai dự án tham khảo hai phiên bản khác nhau của SqlServerCe. Tôi đã đi đến dự án với phiên bản cũ hơn, loại bỏ tham chiếu, sau đó thêm tham chiếu chính xác.

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.

Bạn không phải mở từng bộ phận để xác định các phiên bản của bộ lắp ráp được tham chiếu.

  • Bạn có thể kiểm tra các thuộc tính của từng tài liệu tham khảo.
  • Mở thuộc tính dự án và kiểm tra các phiên bản của phần Tài liệu tham khảo.
  • Mở các dự án với Trình soạn thảo văn bản.
  • Sử dụng .Net Reflector.

5
Giải pháp của bạn có vẻ tốt với tôi, tuy nhiên tôi không nghĩ rằng nó luôn luôn là hữu ích để sử dụng phần Tài liệu tham khảo đến các số xem phiên bản. Tôi thường thấy VS "nói dối" với tôi về phiên bản mà nó đang sử dụng so với phiên bản nào thực sự được đề cập trong tệp .csproj.
David Gardiner

5
@David Gardiner - Tôi đồng ý với tuyên bố "nói dối" của bạn khi sử dụng các dự án C #. Theo kinh nghiệm của tôi, các dự án C # có thể bị nhầm lẫn về phiên bản được tham chiếu và phiên bản thực tế được biên dịch / liên kết. Khi điều này xảy ra, tôi xóa giải pháp, xóa thủ công các thư mục bin và obj, sau đó xóa các cụm dự án tạm thời trong% APPDATA%. Một giải pháp xây dựng lại thường giải quyết vấn đề. (VB hiếm khi bị vấn đề cụ thể này.)
AMissico

54
giành chiến thắng để nói với mọi người thực sự sử dụng cửa sổ đầu ra. Build quá nhiều so với cửa sổ Danh sách Lỗi F5 +.
JJS

2
Như ErikHeemskerk đã đề cập trong câu trả lời của mình, trong Visual Studio 2010, bạn sẽ cần đặt mức độ chi tiết đầu ra thành chi tiết để xem đầu ra của ResolveAss lanhReferences.
Robin Clowers

12
Gợi ý: để tìm vị trí chính xác trong đầu ra của bản dựng dài dòng, sao chép văn bản vào trình soạn thảo văn bản, tìm kiếm "Tìm thấy xung đột giữa các phiên bản khác nhau của cùng một cụm phụ thuộc.".
Contango

133

Mike Hadlow đã đăng một ứng dụng bảng điều khiển nhỏ có tên AsmSpy liệt kê khá độc đáo các tài liệu tham khảo của mỗi hội đồng:

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

Đây là một cách nhanh hơn nhiều để đi đến tận cùng của cảnh báo MSB3247, hơn là phụ thuộc vào đầu ra MSBuild.


1
AsmSpy thật tuyệt vời, bạn chỉ cần nhớ rằng bạn đang tìm kiếm các tài liệu tham khảo về DLL của bên thứ ba với các phiên bản không khớp. Nói chung, các phiên bản không khớp trong các tham chiếu đến các thư viện tiêu chuẩn sẽ không gây ra những cảnh báo này (và bạn sẽ thấy chúng rất nhiều).
Tod Thomson

Đây là một công cụ nhỏ tuyệt vời giúp tôi giải quyết vấn đề của mình ngay lập tức. Tuy nhiên, trong trường hợp của tôi, nó không chính xác là DLL của bên thứ ba, mà là các tham chiếu đến System.Man Quản lý.Automation.dll có các tham chiếu khác nhau đến mscorlib.dll.
Chris Gillum

Công cụ này là tốt, tuy nhiên, nó không hoạt động trong mọi trường hợp. Ít nhất là đối với một dự án .NET 4.5, nó không hiển thị các phiên bản tham chiếu va chạm cho tôi. + đầu ra msbuild đặt tên cho các DLL trong câu hỏi với các đường dẫn và tất cả.
twomm

11
Cảm ơn những lời tốt đẹp các bạn :)
Mike Hadlow

Bạn vừa tiết kiệm cho tôi một số giờ làm việc! Nó đã giúp đọc qua đầu ra chi tiết, nhưng một khi tôi đã làm điều đó một lần nữa dễ dàng xác minh với công cụ của bạn.
Norman H

22

Đôi khi câu trả lời @AMissico là không đủ. Trong trường hợp của tôi, tôi không thể tìm thấy lỗi trong các cửa sổ đầu ra nên tôi quyết định tạo một tệp nhật ký và phân tích nó, bằng cách thực hiện các bước sau:

  1. Lưu nhật ký xây dựng vào một tệp ... https://msdn.microsoft.com/en-us/l Library / ms171470.aspx

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

  2. Tìm văn bản: warning MS...hoặc các thông tin cảnh báo cụ thể: (ví dụ như dòng 9293) Found conflicts between different versions...và các chi tiết đầy đủ các lỗi xung đột sẽ là trên thông điệp này (ví dụ như dòng 9277)There was a conflicts between... Tìm thông báo lỗi

Visual Studio 2013


Gợi ý tuyệt vời để tìm kiếm 3277 trong đầu ra.
sfuqua

21

Tôi thấy rằng (ít nhất là trong Visual Studio 2010), bạn cần đặt mức độ chi tiết đầu ra thành ít nhất là Chi tiết để có thể phát hiện ra vấn đề.

Có thể vấn đề của tôi là một tham chiếu trước đây là tham chiếu GAC, nhưng đó không còn là trường hợp sau khi cài đặt lại máy của tôi.


1
Chuyển đến Công cụ-> Tùy chọn-> Dự án và Giải pháp-> Xây dựng và Chạy để đặt mức độ chi tiết đầu ra.
Farshid

8

Tôi đã có cùng một lỗi và không thể tìm ra nó với các câu trả lời khác. Tôi thấy rằng chúng tôi có thể "Hợp nhất" các gói NuGet.

  1. Nhấp chuột phải vào giải pháp
  2. Nhấp vào Quản lý gói Nuget
  3. Hợp nhất tab và cập nhật lên cùng một phiên bản.

7

Cảnh báo này được tạo cho ASP.NET MVC 4 beta mặc định xem tại đây

Trong, mọi cảnh báo này có thể được loại bỏ bằng cách chỉnh sửa thủ công tệp .csproj cho dự án của bạn.

sửa đổi ........: Tham khảo Bao gồm = "System.Net.Http"

để đọc ......: Tham khảo Bao gồm = "System.Net.Http, Version = 4.0.0.0"


1
Tôi đã làm theo điều này và lỗi đã biến mất. Vẫn không biết làm thế nào hoặc tại sao, tôi đã bắt đầu một dự án MVC 4 với VS2010 sau đó di chuyển trên VS2012. Tuy nhiên, việc thêm thuộc tính phiên bản, làm cho lỗi biến mất. Cảm ơn
MaiOM

6

Sử dụng một trình đọc phụ thuộc

Sử dụng dep.exe, bạn có thể liệt kê tất cả các phụ thuộc lồng nhau của toàn bộ thư mục. Kết hợp với các công cụ unix như grep hoặc awk, nó có thể giúp bạn giải quyết vấn đề của mình

Tìm kiếm các hội đồng được tham chiếu trong nhiều hơn một phiên bản

$ 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            

Dòng lệnh tối nghĩa này chạy dep.exe sau đó chuyển đầu ra hai lần để awk tới

  • đặt cha mẹ và con vào một cột duy nhất (theo mặc định mỗi dòng chứa một cha mẹ và một đứa trẻ để thể hiện sự thật rằng cha mẹ này phụ thuộc vào đứa trẻ đó)
  • sau đó thực hiện một loại 'nhóm bằng cách' sử dụng một mảng kết hợp

Hiểu cách lắp ráp này được kéo vào thùng của bạn

$ 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 

Trong ví dụ này, công cụ sẽ cho bạn thấy System.Web.Http 5.2.3 xuất phát từ sự phụ thuộc của bạn vào FooLib trong khi phiên bản 4.0.0 đến từ BarLib.

Sau đó, bạn có sự lựa chọn giữa

  • thuyết phục chủ sở hữu của libs sử dụng cùng một phiên bản
  • ngừng sử dụng chúng
  • thêm chuyển hướng ràng buộc trong tệp cấu hình của bạn để sử dụng phiên bản mới nhất

Làm thế nào để chạy những thứ này trong Windows

Nếu bạn không có loại vỏ unix, bạn cần tải xuống một cái trước khi có thể chạy awkgrep. Hãy thử một trong những điều sau đây


4

Tôi cũng gặp vấn đề này và sử dụng lời khuyên của AMissico cũng phát hiện ra vấn đề (Mặc dù phải đặt mức độ chi tiết thành Chi tiết.

Vấn đề thực sự khá đơn giản mặc dù sau khi tìm ra thủ phạm.

Bối cảnh: Tôi đã nâng cấp dự án của mình từ VS2008 lên VS2010. Trong VS2008, khung mục tiêu là 3,5 và khi tôi đưa nó vào VS2010, tôi đã chuyển nó thành 4 (Đầy đủ). Tôi cũng đã nâng cấp một số thành phần của bên thứ ba bao gồm các báo cáo Crystal.

Nó chỉ ra hầu hết các tham chiếu Hệ thống khi chỉ vào phiên bản 4.0.0.0 nhưng một cặp đôi đã không được tự động thay đổi (System và System.Web.Service) và vẫn đang xem xét 2.0.0.0. Các báo cáo của Crystal đang tham chiếu 4.0.0.0 và vì vậy đây là nơi xảy ra xung đột. Chỉ cần đặt con trỏ tại thư viện Hệ thống đầu tiên trong trình khám phá giải pháp, con trỏ xuống danh sách và tìm bất kỳ tham chiếu nào đến 2.0.0.0, loại bỏ và thêm lại phiên bản 4.0.0.0 mới hơn đã thực hiện thủ thuật.

Điều kỳ lạ là hầu hết các tài liệu tham khảo đã được cập nhật chính xác và nếu không có báo cáo về Crystal, có lẽ tôi sẽ không bao giờ nhận thấy ...



2

Như đã đề cập ở đây , bạn cần xóa các tài liệu tham khảo không sử dụng và các cảnh báo sẽ đi.


1

Trình quản lý xây dựng ASP.NET đang xây dựng trang web bằng cách đi qua các thư mục theo thứ tự bảng chữ cái và với mỗi thư mục, nó chỉ ra các phụ thuộc và xây dựng các phụ thuộc trước và sau đó là thư mục đã chọn.

Trong trường hợp này, thư mục có vấn đề là ~ / Điều khiển, được chọn để xây dựng ngay từ đầu, vì một lý do chưa biết, nó xây dựng một số điều khiển ở đó như một hội đồng riêng thay vì bên trong cùng một hội đồng như các điều khiển khác (dường như được kết nối với thực tế là một số điều khiển phụ thuộc vào các điều khiển khác trong cùng một thư mục).

Sau đó, thư mục tiếp theo được xây dựng (~ / Trung tâm tệp / Điều khiển) phụ thuộc vào thư mục gốc ~ / phụ thuộc vào ~ / Điều khiển, do đó, thư mục ~ / Điều khiển chỉ được xây dựng lại lần này khi các điều khiển được tách ra để lắp ráp riêng của họ bây giờ được tham gia vào cùng một hội đồng như các điều khiển khác với lắp ráp riêng biệt vẫn đang được tham chiếu.

Vì vậy, tại thời điểm này, 2 lắp ráp (ít nhất) có cùng các điều khiển và quá trình xây dựng thất bại.

Mặc dù chúng tôi vẫn không biết tại sao điều này xảy ra, chúng tôi có thể khắc phục bằng cách thay đổi tên thư mục Điều khiển thành ZControls, theo cách này nó không được xây dựng trước ~ / Trung tâm tệp / Điều khiển, chỉ sau và cách này được xây dựng như là nó phải như thế.


1

Khắc phục nhanh:

Nhấp chuột phải vào giải pháp -> Quản lý các gói NuGet cho giải pháp -> Trong phần Hợp nhất, bạn có thể xem liệu có các phiên bản khác nhau của cùng một gói đã được cài đặt hay không. Gỡ cài đặt các phiên bản khác nhau và cài đặt phiên bản mới nhất.


1

Đôi khi AutoGenerateBindingRedirectskhông đủ (ngay cả với GenerateBindingRedirectsOutputType). Tìm kiếm tất cả các There was a conflictmục và sửa từng cái một cách thủ công có thể rất tẻ nhạt, vì vậy tôi đã viết một đoạn mã nhỏ để phân tích đầu ra nhật ký và tạo chúng cho bạn (kết xuất 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);

Mẹo: sử dụng Trình xem nhật ký nhị phân và cấu trúc MSBuild và chỉ tạo các chuyển hướng ràng buộc cho các xung đột trong dự án phát ra cảnh báo (nghĩa là chỉ vượt qua các there was a conflictdòng đó vào tệp văn bản đầu vào cho mã ở trên [ AssemblyConflicts.txt]).


0

Một cách đơn giản nhất mà không cần phải tính đến các phụ thuộc (nội bộ):

  1. Mở "Giải pháp thám hiểm".
  2. Nhấp vào "Hiển thị tất cả các tệp"
  3. Mở rộng "Tài liệu tham khảo"
  4. Bạn sẽ thấy một (hoặc nhiều) tài liệu tham khảo có biểu tượng hơi khác so với phần còn lại. Thông thường, nó có hộp màu vàng đề nghị bạn ghi chú lại. Chỉ cần loại bỏ nó.
  5. Thêm tham chiếu trở lại và biên dịch mã của bạn.
  6. Đó là tất cả.

Trong trường hợp của tôi, có một vấn đề với tham chiếu MySQL. Bằng cách nào đó, tôi có thể liệt kê ba phiên bản của nó trong danh sách tất cả các tài liệu tham khảo có sẵn. Tôi đã làm theo quy trình 1 đến 6 ở trên và nó đã làm việc cho tôi.


0

Bổ sung Visual Studio cho Mac Community:

câu trả lời của AMissico yêu cầu thay đổi cấp độ nhật ký và cả ASMSpy và ASMSpyPlus đều không có sẵn dưới dạng giải pháp đa nền tảng, đây là một bổ sung ngắn cho Visual Studio cho Mac:

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

Đó là trong Cộng đồng Visual Studio → Tùy chọn ... → Dự án → Nhật ký xây dựng → mức độ chi tiết


0

Nếu bạn đã chia sẻ lại, hãy xóa tất cả các tham chiếu không sử dụng trên giải pháp của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.