在构建失败后运行MSBuild目标

5

我定制的MSBuild任务在实际构建之前和之后执行一些步骤。保证在构建后执行清理文件的步骤非常重要。目前我定义了两个目标:

<Target Name="NrtPatchAssemblyInfo" BeforeTargets="BeforeBuild">

并且

<Target Name="NrtRestoreAssemblyInfo" AfterTargets="AfterBuild">

第一个任务总是会被执行,但只有在成功构建后才会执行第二个任务。例如,如果编译器由于代码文件中的语法错误而导致构建失败,则第二个目标不会运行。

我该怎么做才能改变这一点,让第二个任务始终被执行?

我找不到MSBuild通常使用的目标名称列表。这些名称只是从其他来源复制而来。

1个回答

4
当出现错误时,MsBuild会停止运行任何进一步的目标(除非ContinueOnError在某处被修改,但您无法编辑所有已安装的msbuild文件以使其工作)。一个解决方案是使用OnError元素。这必须设置在失败的目标上(或者该目标的父级,我假设),因此您将不得不选择一个在实际构建中使用的目标并覆盖它。对于C++构建,您需要覆盖Build目标,复制Microsoft.Common.CurrentVersion.targets中的定义并添加OnError。示例代码(必须在Microsoft.Cpp.targets导入之后插入项目文件中!):
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Target Name="RunOnError">
  <Message Text="OOPS!" />
</Target>
<Target
    Name="Build"
    Condition="'$(_InvalidConfigurationWarning)' != 'true'"
    DependsOnTargets="$(BuildDependsOn)"
    Returns="$(TargetPath)">
  <OnError ExecuteTargets="RunTargetAfterBuild" />
</Target>

要确定哪些目标会被执行,只需使用详细的冗长度运行构建即可。

如果没有完成目标时,该如何执行清理工作或其他错误后的必要操作呢?对我来说,复制 Visual Studio 基础设施并非一个选择(至少还不是)。 - ygoe
1
你也可以避免清理工作:在我看来,这是一个更容易的解决方法。复制你想要修补程序集信息的任何文件,将其复制到中间目录或其他地方,并在构建中使用该副本。如果对副本进行的更改没有被还原,也没有关系。 - stijn
我终于回到了这个话题。我已经更改了我的工具,不再在原地修补和恢复文件,而是将修改后的文件保存到 obj\ 并使用它(Include)代替原始文件(Remove)。 - ygoe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接