Как я могу использовать объекты BeforeBuild и AfterBuild с помощью Visual Studio 2017?
После перехода на csproj для использования Visual Studio 2017 и Microsoft.NET.Sdk мои целевые объекты "BeforeBuild" и "AfterBuild" больше не работают. Мой файл выглядит следующим образом:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net46</TargetFramework>
</PropertyGroup>
<!-- my targets that don't run -->
<Target Name="BeforeBuild">
<Message Text="Should run before build" Importance="High" />
</Target>
<Target Name="AfterBuild">
<Message Text="Should run after build" Importance="High" />
</Target>
</Project>
Ответы
Ответ 1
Связанная с этим проблема с MSBuild git рекомендует не использовать BeforeBuild/AfterBuild в качестве имен задач в будущем, вместо этого присваивать имя задаче соответствующим образом и связывать ее с целями
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net46</TargetFramework>
</PropertyGroup>
<!-- Instead of BeforeBuild target -->
<Target Name="MyCustomTask" BeforeTargets="CoreBuild" >
<Message Text="Should run before build" Importance="High" />
</Target>
<!-- Replaces AfterBuild target -->
<Target Name="AnotherCustomTarget" AfterTargets="CoreCompile">
<Message Text="Should run after build" Importance="High" />
</Target>
</Project>
Это дает вам файл проекта idiomatic VS 2017, но какие цели вы активируете до/после, все еще остается предметом споров в настоящее время.
Ответ 2
Когда вы указываете Project Sdk="Microsoft.NET.Sdk"
, вы используете "имплицированный верхний и нижний импорт". Это означает, что есть невидимый импорт в Microsoft.NET.Sdk/Sdk.targets в нижней части вашего файла csproj, который переопределяет цели "BeforeBuild" и "AfterBuild".
Вы можете исправить это, используя явные импорт, чтобы вы могли контролировать порядок импорта.
<Project>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup>
<TargetFramework>net46</TargetFramework>
</PropertyGroup>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
<!-- add your custom targets after Sdk.targets is imported -->
<Target Name="BeforeBuild">
<Message Text="Should run before build" Importance="High" />
</Target>
<Target Name="AfterBuild">
<Message Text="Should run after build" Importance="High" />
</Target>
</Project>
Ответ 3
В уже упомянутом выпуске GitHub Rainer Sigwald предлагает гораздо более короткое и элегантное решение:
<Target Name="CustomBeforeBuild" BeforeTargets="BeforeBuild"> ... </Target>
<Target Name="CustomAfterBuild" AfterTargets="AfterBuild"> ... </Target>
Выглядит странно, но работает отлично.