在Build Server上使用BeforeTargets ="Build"时,目标未运行

Chr*_*son 8 msbuild teamcity

我有一个自定义的.targets文件,我将其导入到我的C#MVC Web应用程序的项目文件中.我已经为此添加了自定义目标:

<Target Name="CopyFiles" BeforeTargets="Build"></Target>
Run Code Online (Sandbox Code Playgroud)

这在Visual Studio下构建时工作正常,但是当我使用TeamCity构建它时,目标永远不会运行,我无法解决原因.

如果我改变目标使用BeforeTargets ="Compile",那么它就会运行.或者,如果我将名为Build的其他目标添加到.targets文件中

<Target Name="Build" />
Run Code Online (Sandbox Code Playgroud)

然后它会运行,但这样做会覆盖现有的Build目标,因此我的应用程序不会构建.我无法弄清楚这个逻辑 - 它没有意义.我现在正在使用Compile目标,但是如果有人可以解释为什么在Build任务不起作用之前尝试执行它我会非常感激.

hgc*_*ngs 9

"构建"是一个特殊的内置目标,因此与其他大多数目标的工作方式不同.它绝对不能安全地被覆盖.

最相关的文档在这里:https://msdn.microsoft.com/en-us/library/ms366724.aspx

如果您希望在构建之前运行某些内容,则标准方法(由新创建的.csproj文件中的注释推荐)将覆盖BeforeBuild目标(如上所述).

但是,这不是最强大的解决方案.如上文所述:

覆盖预定义目标是扩展构建过程的简单方法,但是,由于MSBuild按顺序评估目标定义,因此无法阻止导入项目的其他项目覆盖已覆盖的目标.

覆盖BuildDependsOn属性并扩展此属性的默认值以包含您要运行的目标(这也在上面的链接中记录)更好(并且稍微复杂一点).

另一种方法是将BeforeBuild保持为空并使用BeforeTargets="BeforeBuild",这感觉有点奇怪,但非常简单,即使OverBuild目标被覆盖也仍然有效.

至于为什么BeforeTargets="Build"不起作用,我在文档中找不到这方面的参考,但我认为这与它的特殊性质有关.它与普通目标的工作方式不同,最好不要将其视为目标.

  • 这是不正确的,`Build`在`Microsoft.Common.CurrentVersion.targets`中定义,其行为与任何其他目标一样.`BeforeTargets ="Build"`完全有效.问题是`Build`目标是一个没有实际身体的虚拟目标,并不总是根据情况调用.具体情况因VS版本和项目类型而异,特别是对于涉及太多变体的Web项目.这就是为什么`BeforeBuild`作为基于`Micrsoft.Common.targets`的所有内容的保证扩展点的原因. (12认同)