MSBuild заменяет Newtonsoft.Json.dll на более старую версию - PullRequest
0 голосов
/ 01 июня 2018

Я использую программу MSBuild в TeamCity для создания веб-API ASP.net и запускаю модульные тесты.Все работало, пока я не обновился до «Microsoft Build Tools 2017 15.7.2».

Внезапно msbuild копировал старую версию Newtonsoft.Json.dll (версия 6.0.4.17603) из «C: \ Program Files (x86) \ ISS \ Microsoft Web Deploy V3» или «C: \ Program».Файлы \ ISS \ Microsoft Web Deploy V3 "в выходную папку при создании решения.Все проекты ссылаются на версию 9.0.1, используя NuGet.

Наблюдая за выходной папкой во время сборки, я мог видеть, как DLL переключается между 6.0.4 и 9.0.1 до сборки.закончилась, и версия 6.0.4 осталась.

Я нашел этот вопрос , и когда я переименовал файлы Newtonsoft.Json.dll в Web, разверните папки в Newtonsoft.Json_old.dll ",msbuild не заменил мою версию 9.0.1, и все работало нормально.

Я проверил, что все проекты, ссылающиеся на Newtonsoft.Json, ссылаются на версию 9.0.1 и используют правильный Hint-Path в .csproj.файлы.

Кто-нибудь знает, как решить проблему? Мое решение больше похоже на обходной путь, и я хотел бы знать, почему msbuild сначала копирует этот файл.

Ответы [ 2 ]

0 голосов
/ 16 мая 2019

Сводка

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

В файле проекта, подверженного уязвимости, найдите следующую строку:

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

И добавьте это ниже:

<PropertyGroup>
    <AssemblySearchPaths>$(AssemblySearchPaths.Replace('{AssemblyFolders}', '').Split(';'))</AssemblySearchPaths>
</PropertyGroup>

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


Полная версия

Моя команда выполнилав аналогичную проблему, когда мы перешли на Visual Studio 2019. Некоторые из наших проектов все еще нацелены на .NET Framework 4.0, и после установки Visual Studio 2019 на наших агентах сборки мы начали получать загадочную ошибку с проектами, которые ссылались на некоторые из наших основных библиотек.:

Первичная ссылка "OurCoreLibrary, версия = 3.4.2.0, Culture = нейтральная, PublicKeyToken = xxxxxxxxxxxxxxxx, processorArchitecture = MSIL" не может быть разрешена, поскольку она имеет косвенную зависимость от сборки "Newtonsoft.Json, версия = 9.0.0.0, культура = нейтральная, PublicKeyToken = 30ad4fe6b2a6aeed ", которая была построена против" .NETFramework, Версия = v4.5 "фреймворк.Это более высокая версия, чем целевая на данный момент платформа .NETFramework, Version = v4.0.

Проблема исчезла после переключения проекта на целевой 4.5, но по причинам, которые я не получуздесь мы не могли сделать это для каждого затронутого проекта, поэтому я решил углубиться в него.

Как выяснилось, ваш вопрос дал некоторое представление о том, что происходит.Версия Newtonsoft.Json, на которую мы ссылались, соответствовала версии в «C: \ Program Files (x86) \ ISS \ Microsoft Web Deploy V3», и когда я удалил файл, сборка прошла успешно.

Нашаособая проблема заключалась в том, что копия Newtonsoft.Json в папке Web Deploy была той же версии (9.0.0.0), но неправильной структуры (4.5 вместо 4.0), и по какой-то причине логика разрешения не проверяет целевую среду,вызывая несоответствие во время сборки.Обновление до VS2019 включало обновление Web Deploy, которое также обновляло эту копию Newtonsoft.Json до 9.0.0.0, вызывая нашу коллизию.

Чтобы увидеть, почему эта сборка даже рассматривалась с самого начала, я установил MSBuildподробности проекта сборки сборки до Diagnostic и взглянули на происходящее.Поиск неправильного пути показал, что в задаче ResolveAssemblyReferences MSBuild просматривал некоторые неожиданные места для поиска совпадений:

1>          For SearchPath "{AssemblyFolders}". (TaskId:9)
1>          Considered "C:\Program Files (x86)\Microsoft.NET\ADOMD.NET\140\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1>          Considered "C:\Program Files (x86)\Microsoft.NET\ADOMD.NET\140\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1>          Considered "C:\Program Files (x86)\Microsoft.NET\ADOMD.NET\140\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)
1>          Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1>          Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1>          Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)
1>          Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1>          Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1>          Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)
1>          Considered "C:\Program Files\IIS\Microsoft Web Deploy V3\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1>          Considered "C:\Program Files\IIS\Microsoft Web Deploy V3\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1>          Considered "C:\Program Files\IIS\Microsoft Web Deploy V3\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)
1>          Considered "C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1>          Considered "C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1>          Considered "C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)

Дальнейшее копание показывает, что искомые пути передаются как AssemblySearchPaths, который определен в Microsoft.Common.CurrentVersion.targets :

<AssemblySearchPaths Condition=" '$(AssemblySearchPaths)' == ''">
  {CandidateAssemblyFiles};
  $(ReferencePath);
  {HintPathFromItem};
  {TargetFrameworkDirectory};
  $(AssemblyFoldersConfigFileSearchPath)
  {Registry:$(FrameworkRegistryBase),$(TargetFrameworkVersion),$(AssemblyFoldersSuffix)$(AssemblyFoldersExConditions)};
  {AssemblyFolders};
  {GAC};
  {RawFileName};
  $(OutDir)
</AssemblySearchPaths>

Согласно справочнику задач MSBuild для задачи ResolveAssemblyReferences , SearchPathsпараметр определяется как:

Указывает каталоги или специальные местоположения, в которых производится поиск файлов на диске, представляющих сборки.Порядок, в котором перечислены пути поиска, важен.Для каждой сборки список путей ищется слева направо.Когда файл, представляющий сборку, найден, поиск прекращается и начинается поиск следующей сборки.

... и он определяет несколько специальных констант, включая нашего друга {AssemblyFolders}:

  • {AssemblyFolders}: указывает, что задача будет использовать схему поиска сборок из реестра Visual Studio.NET 2003.

Поскольку каталогипроверены по порядку, вы можете ожидать, что {HintPathFromItem} будет иметь приоритет, и в большинстве случаев это так.Однако, если у вас есть зависимость с зависимостью от более старой версии Newtonsoft.Json, для этой версии не будет HintPath , и он будет продолжаться до разрешения.

Позже в Microsoft.Common.CurrentVersion.targets мы можем видеть, что есть случаи, когда эта константа явно удаляется, откуда и приходит ответ выше:

<PropertyGroup Condition="'$(_TargetFrameworkDirectories)' == '' and '$(AssemblySearchPaths)' != '' and '$(RemoveAssemblyFoldersIfNoTargetFramework)' == 'true'">
  <AssemblySearchPaths>$(AssemblySearchPaths.Replace('{AssemblyFolders}', '').Split(';'))</AssemblySearchPaths>
</PropertyGroup>

Удаление этой константы удаляет проблемные папки из рассмотрения, и, честно говоря, я не могу вспомнить ситуацию, когда я хотел бы, чтобы сборка неявно разрешалась в любой версии, скажем, Newtonsoft.Json, которая зависала в Web Deploy или SQL Server.Папка SDK.При этом, я уверен, что есть случай, когда отключение может вызвать проблемы у кого-то, так что имейте это в виду.

0 голосов
/ 01 июня 2018

Возможно, стоит запустить пользовательскую сборку и поставить галочку «очистить все файлы в каталоге извлечения перед сборкой» - у вас могут остаться конфликтующие инструменты сборки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...