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

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

  •  18-09-2019
  •  | 
  •  

Вопрос

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

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

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

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

Это было полезно?

Решение

Измените "Детализацию выходных данных MSBuild project build" на "Подробный" или выше.Чтобы сделать это, выполните следующие действия:

  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.

Другие советы

У Майка Хэдлоу есть опубликовал небольшое консольное приложение под названием 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.

Иногда ответа @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... Find the error message

Visual Studio 2013

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

Возможно, моя проблема заключалась в ссылке, которая ранее была ссылкой GAC, но после переустановки моего компьютера это перестало иметь место.

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

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

модифицировать........:Ссылка включает="System.Net.Http"

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

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

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

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

Используя 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.Попробуйте одно из следующих действий

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

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

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

Оказалось, что большинство системных ссылок указывают на версию 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 reports, я, вероятно, никогда бы этого не заметил...

Я сделал заявку, основанную на Приложение Майка Хэдлоу:AsmSpy ( Шпион ).

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

Код доступен по адресу: ГитХаб

Gui Sample

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

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

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

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

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

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

Быстрое решение:

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

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

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

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

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

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

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

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

Это в Сообщество Visual Studio → Предпочтения...→ Проекты → Журнал сборки → детализация

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top