Устранить зависимости NuGet внешнего проекта.NET 4.7 с помощью целей MSBuild
Нам нужно заставить эти проекты строить, и у них есть странные практики. Они полагаются на файлы связанного кода, которые генерируются в результате процесса сборки другого проекта. Эти проекты находятся в подпапке.
Таким образом, прежде чем строить наши проекты, нам нужно построить подпроект. Это делается путем добавления пользовательской цели сборки в цель BeforeBuild каждого проекта, и, похоже, работает. Однако, подпроект не будет построен без восстановления зависимостей NuGet.
Для пояснения: мы знаем, что этот шаблон полностью помешан, но у нас нет ничего подобного персоналу для рефакторинга каждого проекта, который использует этот шаблон. Мы просто пытаемся заставить их надежно скомпилировать за один шаг.
Каждая из этих внешних зависимостей проекта указана в пользовательской ItemGroup, например:
<ItemGroup>
<ExternalDependantProjects Include= "..\<subfolder>\<project>\<project>.csproj" />
</ItemGroup>
Мы пытались решить эту проблему, добавляя пользовательские цели сборки, которые вызываются целью BeforeBuild каждого проекта. Сначала мы попытались использовать ResolveNuGetPackageAssets в качестве цели сборки, но обнаружили, что это поддерживается только в netcore, в то время как мы нацелены на net47.
Теперь мы пытаемся написать пользовательскую цель сборки, которая восстановит зависимости NuGet во внешнем проекте. Мы попробовали простой подход, вот так: <Exec Command="nuget restore @(ExternalDependantProjects)" />
и несколько более сложная и хакерская попытка PowerShell: <Exec Command="powershell.exe -command "'@(ExternalDependantProjects, '' '')' | foreach { nuget restore $_ }"" />
В обоих случаях он просто пытается восстановить пакеты основного проекта, а не внешних проектов. Кажется, что @(ExternalDependantProjects) равно пустому, и поэтому новый аргумент не добавляется. Использование показало, что @(ExternalDependantProjects) ничего не возвращает. Тем не менее, он работает как параметр "Projects", когда мы вызываем MSBuild "Build" target. Итак, я подозреваю, что мы используем параметр Item неправильно? Возможно, есть некоторый синтаксис для доступа к свойству Include элемента?
Однако я не уверен, что это сработает, если мы сможем решить эту проблему. Мы протестировали с помощью команды восстановления nuget в подпроекте и всегда получаем ответ, что все пакеты в packages.conf установлены. Тем не менее,.. \ packages \ из этого внешнего проекта пуст, а packages.conf указывает полдюжины пакетов (они также отсутствуют в "References" в VS, и HintPath ссылок правильно переходит в..\packages).
Таким образом, мы сбиты с толку по трем направлениям: как мы ссылаемся на путь включения элемента ExternalDependentProjects из целей MSBuild, почему NuGet не восстанавливает CLI, и является ли это даже правильным способом решения этой проблемы? Мы спустились совсем не по тому пути?
2 ответа
Как мы ссылаемся на путь включения элемента ExternalDependentProjects из целей MSBuild, почему NuGet не может восстановить CLI, и является ли это даже правильным способом решения этой проблемы? Мы спустились совсем не по тому пути?
Вы должны написать свою собственную цель сборки с опцией -OutputDirectory
, поэтому пользовательская цель сборки должна быть такой:
<Target Name="BeforeBuild">
<Exec Command="nuget restore @(ExternalDependantProjects) -OutputDirectory ..\<subfolder>\packages" />
</Target>
С этой целью пакет NuGet для внешних проектов будет успешно восстановлен.
Кроме того, значение @(ExternalDependantProjects)
не равно пустому, вы можете использовать целевой эхо это значение.
Ниже мой тестовый образец, вы можете обратиться к подробной информации:
ExternalpProject
это имя подпапки, TestExternalProject
это имя внешнего проекта.
<ItemGroup>
<ExternalDependantProjects Include= "..\ExternalpProject\TestExternalProject\TestExternalProject.csproj" />
</ItemGroup>
<Target Name="BeforeBuild">
<Message Text="Restore package for Externalp Project" Importance="high"></Message>
<Exec Command="nuget restore @(ExternalDependantProjects) -OutputDirectory ..\ExternalpProject\packages" />
</Target>
<Target Name="AfterBuild">
<Message Text="Display the value of ExternalDependantProjects" Importance="high"></Message>
<Message Text="@(ExternalDependantProjects)"></Message>
</Target>
NuGet обнаруживает проекты package.config для восстановления из файла решения. Если все проекты находятся в файле решения и вы запускаете nuget.exe restore <solution file>
они должны быть восстановлены независимо от того, что происходит в файлах проекта.
В качестве обходного пути для любого пользовательского сценария вы можете написать сценарий для обнаружения всех файлов packages.config в папке, а затем вызвать nuget.exe restore <packages.config> -SolutionDirectory <solution root>
на файлы напрямую. Для восстановления packages.config единственной необходимой частью является обнаружение списка id / версий из файлов packages.config, чтобы их можно было загрузить и извлечь в папку пакетов уровня решения.
Я также предлагаю использовать ссылки проекта с ReferenceOutputAssembly=false
обеспечить, чтобы проекты создавались в нужном вам порядке и без ссылок друг на друга. См.: https://blogs.msdn.microsoft.com/kirillosenkov/2015/04/04/how-to-have-a-project-reference-without-referencing-the-actual-binary/