Устранение MSB3247 - Обнаружены конфликты между различными версиями одной и той же зависимой сборки

427

Решение .NET 3.5 заканчивалось этим предупреждением при компиляции с msbuild.

Иногда NDepend может помочь, но в этом случае он не дает никаких дополнительных подробностей. Как и Бобу, мне пришлось прибегнуть к открытию каждой сборки в ILDASM, пока я не нашел ту, которая ссылалась на более старую версию зависимой сборки.

Я действительно пытался использовать MSBUILD из VS 2010 Beta 2 (как указывалось в статье о подключении, это было исправлено в следующей версии CLR), но это также не давало более подробной информации (возможно, исправлено после Beta 2)

Есть ли лучший (более автоматизированный) подход?

Дэвид Гардинер
источник
2
В моем случае мне просто нужно было убедиться, что на всех проектах в решении была запущена одна и та же версия пакетов nuget (можно просто обновить все до последней версии).
Майкл

Ответы:

576

Измените «Детальность вывода сборки проекта MSBuild» на «Подробно» или выше. Для этого выполните следующие действия:

  1. Откройте диалоговое окно «Параметры» ( Инструменты -> Параметры ... ).
  2. В левом дереве выберите узел « Проекты и решения» , а затем выберите « Построить и запустить» .
    • Примечание. Если этот узел не отображается, убедитесь, что в нижней части диалогового окна « Показать все настройки» установлен флажок.
  3. На открывшейся странице инструментов / параметров установите уровень детализации выходных данных сборки проекта MSBuild в зависимости от вашей версии:

  4. Постройте проект и посмотрите в окне вывода.

Проверьте сообщения MSBuild. ResolveAssemblyReferencesЗадача, это задача , с которой MSB3247 берет свое начало, должно помочь вам отладить этот конкретный вопрос.

Мой конкретный случай был неправильной ссылкой на SqlServerCe. См. ниже. У меня было два проекта, ссылающихся на две разные версии SqlServerCe. Я пошел в проект с более старой версией, удалил ссылку, затем добавил правильную ссылку.

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.

Вам не нужно открывать каждую сборку, чтобы определить версии ссылочных сборок.

  • Вы можете проверить свойства каждой ссылки.
  • Откройте свойства проекта и проверьте версии раздела «Ссылки».
  • Откройте проекты с помощью текстового редактора.
  • Используйте .Net Reflector.
AMissico
источник
5
Ваши решения выглядят хорошо для меня, однако я не думаю, что всегда полезно использовать раздел «Ссылки» для просмотра номеров версий. Я часто видел, как VS «врал» мне о том, какую версию он использует, а какую версию на самом деле упоминают в файле .csproj.
Дэвид Гардинер
5
@ Дэвид Гардинер - я бы согласился с вашим «ложным» утверждением при использовании проектов на C #. По моему опыту, C # проекты могут запутаться в отношении ссылочной версии и фактической версии, скомпилированной / связанной. Когда это происходит, я очищаю решение, вручную удаляю папки bin и obj, затем удаляю временные сборки проекта в% APPDATA%. Решение восстановления обычно решает проблему. (VB редко страдает от этой конкретной проблемы.)
AMissico
54
поблагодарить людей за то, что они на самом деле используют окно вывода. Сборка - это намного больше, чем окно списка ошибок F5 +.
JJS
2
Как упомянул ErikHeemskerk в своем ответе, в Visual Studio 2010 вам необходимо установить подробность вывода, чтобы увидеть выходные данные ResolveAssemblyReferences.
Робин Кловерс
12
Подсказка: чтобы найти точное место в подробном выводе сборки, скопируйте текст в текстовый редактор, найдите «Обнаружены конфликты между различными версиями одной и той же зависимой сборки».
Контанго
133

Майк Хэдлоу опубликовал небольшое консольное приложение под названием AsmSpy, в котором довольно приятно перечисляются ссылки на каждую сборку:

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

Это гораздо более быстрый способ добраться до сути предупреждения MSB3247, чем зависеть от вывода MSBuild.

Ноэль Абрахамс
источник
1
AsmSpy потрясающий, вам просто нужно помнить, что вы ищете ссылки на сторонние библиотеки DLL с несовпадающими версиями. Как правило, несовпадающие версии в ссылках на стандартные библиотеки не вызовут этих предупреждений (и вы увидите их много).
Тод Томсон
Это отличный маленький инструмент, который помог мне немедленно решить мою проблему. В моем случае, однако, это были не сторонние библиотеки DLL, а ссылки на System.Management.Automation.dll, которые имели разные ссылки на mscorlib.dll.
Крис Гиллум,
Инструмент хорош, однако, он не работает при любых обстоятельствах. По крайней мере, для проекта .NET 4.5 для меня не было встречных версий ссылок. + msbuild выводит имена рассматриваемых DLL с путями и всем.
twomm
11
Спасибо за добрые слова, ребята :)
Майк Хэдлоу
Вы только что сэкономили мне несколько часов работы! Это помогло прочитать подробный вывод, но как только я это сделал, было легко снова проверить с помощью вашего инструмента.
Норман Х
22

Иногда @AMissico ответа недостаточно. В моем случае я не смог найти ошибку в окнах вывода, поэтому я решил создать файл журнала и проанализировать его, выполнив следующие шаги:

  1. Сохранение журнала сборки в файл ... https://msdn.microsoft.com/en-us/library/ms171470.aspx

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

  2. Найдите текст: warning MS...или конкретную информацию о предупреждении: (например, строка 9293), Found conflicts between different versions...и полная информация об ошибке конфликта будет выше этого сообщения (например, строка 9277)There was a conflicts between... Найти сообщение об ошибке

Visual Studio 2013

Jaider
источник
Отличный совет для поиска 3277 в выводе.
sfuqua
21

Я обнаружил, что (по крайней мере, в Visual Studio 2010) вам нужно установить выходную детализацию, по крайней мере, Подробную, чтобы можно было выявить проблему.

Может быть, моя проблема была ссылкой, которая ранее была ссылкой GAC, но это было уже не так после переустановки моей машины.

ErikHeemskerk
источник
1
Перейдите в Инструменты-> Параметры-> Проекты и решения-> Построить и запустить, чтобы установить подробность вывода.
Farshid
8

У меня была такая же ошибка, и я не мог понять это с другими ответами. Я обнаружил, что мы можем «консолидировать» пакеты NuGet.

  1. Щелкните правой кнопкой мыши на решении
  2. Нажмите Управление пакетами Nuget
  3. Закрепить вкладку и обновить до той же версии.
Кэрол
источник
7

Это предупреждение генерируется для бета-версии ASP.NET MVC 4 по умолчанию, см. Здесь

В любом приведении это предупреждение может быть устранено путем ручного редактирования файла .csproj для вашего проекта.

изменить ........: Ссылка Включить = "System.Net.Http"

читать ......: Ссылка Включить = "System.Net.Http, Версия = 4.0.0.0"

RouR
источник
1
Я последовал за этим, и ошибка исчезла. До сих пор не знаю, как и почему, я запустил проект MVC 4 с VS2010, а затем перенес на VS2012. Однако, добавив атрибут version, ошибка исчезла. Спасибо
MaiOM
6

Используйте читателя зависимостей

Используя dep.exe, вы можете перечислить все вложенные зависимости всей папки. В сочетании с инструментами Unix, такими как grep или awk, он может помочь вам решить вашу проблему

Поиск сборок, на которые есть ссылки в более чем одной версии

$ 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            

Эта неясная командная строка запускает dep.exe, затем дважды передает выходные данные в awk

  • поместить родителя и потомка в один столбец (по умолчанию каждая строка содержит одного родителя и потомка, чтобы выразить тот факт, что этот родитель зависит от этого потомка)
  • затем сделать своего рода «группировать по» с использованием ассоциативного массива

Понимание того, как эта сборка оказалась в вашей корзине

$ 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 

В этом примере инструмент покажет вам, что System.Web.Http 5.2.3 происходит от вашей зависимости от FooLib, а версия 4.0.0 - от BarLib.

Тогда у вас есть выбор между

  • убедить владельцев библиотек использовать ту же версию
  • прекратить использовать их
  • добавление перенаправлений привязки в файл конфигурации для использования последней версии

Как запустить эти вещи в Windows

Если у вас нет оболочки типа Unix, вам необходимо скачать ее, прежде чем запускать awk и grep. Попробуйте одно из следующих

Манитра Андриамитондра
источник
4

У меня тоже была эта проблема, и я воспользовался советом AMissico, чтобы выяснить проблему (хотя для уровня детализации пришлось установить значение «Подробно».

Проблема была на самом деле довольно прямой, хотя после обнаружения виновника.

Предыстория: я обновил свой проект с VS2008 до VS2010. В VS2008 целевой фреймворк был 3.5, и когда я перенес его в VS2010, я переключил его на 4 (Full). Я также обновил некоторые сторонние компоненты, включая отчеты Crystal.

Оказалось, что большинство ссылок System, где указывалось на версию 4.0.0.0, но пара не была автоматически изменена (System и System.Web.Services) и все еще смотрели на 2.0.0.0. Crystal Reports ссылается на 4.0.0.0, и именно здесь возникли конфликты. Просто поместив курсор на первую Системную библиотеку в обозревателе решений, наведите курсор вниз по списку и ищите любые ссылки на 2.0.0.0, удаляя и повторно добавляя более новую версию 4.0.0.0, сделали свое дело.

Странно то, что большинство ссылок было правильно обновлено, и если бы не отчеты Crystal, я бы, наверное, никогда бы этого не заметил ...

Hamiora
источник
2

Я сделал приложение на основе приложения Майка Хэдлоу: AsmSpy .

Мое приложение представляет собой приложение WPF с графическим интерфейсом и может быть загружено с моего домашнего веб-сервера: AsmSpyPlus.exe .

Код доступен по адресу: GitHub

Образец Gui

Эрик Оуэлл
источник
2

Как упомянуто здесь , вам нужно удалить неиспользованные ссылки, и предупреждения уйдут.

lex87
источник
1

ASP.NET build manager строит веб-сайт, просматривая папки в алфавитном порядке, и для каждой папки он определяет свои зависимости и сначала строит зависимости, а затем выбранную папку.

В этом случае проблемная папка ~ / Controls выбирается для создания в начале, но по неизвестной причине она создает некоторые элементы управления там как отдельную сборку, а не внутри той же сборки, что и другие элементы управления (кажется, быть связано с тем, что некоторые элементы управления зависят от других элементов управления в той же папке).

Затем следующая создаваемая папка (~ / File-Center / Control) зависит от корневой папки ~ /, которая зависит от ~ / Controls, поэтому папка ~ / Controls строится снова только на этот раз, когда элементы управления были разделены к своей собственной сборке теперь присоединяются к той же сборке, что и другие элементы управления, при этом на отдельную сборку все еще ссылаются.

Таким образом, на этом этапе 2 сборки (по крайней мере) имеют одинаковые элементы управления, и сборка завершается неудачно.

Хотя мы до сих пор не знаем, почему это произошло, мы смогли обойти это, изменив имя папки Controls на ZControls, таким образом, оно не собирается до ~ / File-Center / Control, а только после и таким образом оно создается как это должно.

Майк Йингер
источник
1

Быстрая починка:

Щелкните правой кнопкой мыши решение -> Управление пакетами NuGet для решения -> В разделе Консолидация вы можете увидеть, были ли установлены разные версии одного и того же пакета. Удалите разные версии и установите последнюю.

JerryGoyal
источник
1

Иногда AutoGenerateBindingRedirectsне достаточно (даже с GenerateBindingRedirectsOutputType). Поиск всех There was a conflictзаписей и их ручное исправление могут быть утомительными, поэтому я написал небольшой фрагмент кода, который анализирует выходные данные журнала и генерирует их для вас (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);

Совет: используйте MSBuild Binary and Structured Log Viewer и генерируйте только перенаправления привязки для конфликтов в проекте, который выдает предупреждение (то есть только после этих there was a conflictстрок во входной текстовый файл для кода выше [ AssemblyConflicts.txt]).

Охад Шнайдер
источник
0

Самый простой способ без учета без учета (внутренних) зависимостей:

  1. Откройте «Обозреватель решений».
  2. Нажмите «Показать все файлы»
  3. Развернуть «Рекомендации»
  4. Вы увидите одну (или более) ссылку (-и) со значком, немного отличающимся от остальных. Как правило, это с желтой рамкой, предлагающей вам принять к сведению. Просто удали это.
  5. Добавьте ссылку назад и скомпилируйте свой код.
  6. Это все.

В моем случае возникла проблема со ссылкой на MySQL. Так или иначе, я мог бы перечислить три его версии под списком всех доступных ссылок. Я следовал процессу с 1 по 6 выше, и он работал для меня.

Сухи
источник
0

Добавление Visual Studio для Mac сообщества:

Поскольку ответ AMissico требует изменения уровня журнала, и ни ASMSpy, ни ASMSpyPlus не доступны в качестве кроссплатформенного решения, вот краткое дополнение для Visual Studio для Mac:

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

Это в сообществе Visual Studio → Настройки ... → Проекты → Журнал сборки → Многословие

SwiftArchitect
источник
0

Если у вас есть резкость, удалите все неиспользуемые ссылки в вашем решении.

Паскаль Кармони
источник