为何执行msbuild /target:C时Target A、D运行而B不运行?
为什么Target A和D运行,但B不运行?
这是个很典型的MSBuild目标触发逻辑细节问题,核心在于Before/AfterTargets 和 DependsOnTargets 对"被跳过的Target"的处理逻辑完全不同,咱们一步步拆解:
首先明确你提到的规则里容易被忽略的关键细节:
当Target的Condition为
'False'时,该Target会被标记为「跳过」——它自身的任务不会执行,但它在构建目标列表中的存在,依然会触发Before/AfterTargets关联的目标;而DependsOnTargets只有在Target实际要执行(Condition为True)时,才会触发依赖链。
现在逐个分析你的Target:
- Target C:你指定了
Condition="'False'",所以它自身的Message任务不会执行,但因为你用/target:C把它列入了构建目标列表,它的"存在"依然会触发关联的Before/After目标。 - Target A(BeforeTargets="C"):BeforeTargets的触发逻辑是「只要目标列表里包含C,不管C是否被跳过,都要在C之前运行A」。因为你明确指定了构建C,所以A会被触发执行。
- Target B(C的DependsOnTargets="B"):DependsOnTargets的触发逻辑是「只有当C本身要被执行(Condition为True)时,才会先运行它的依赖B」。由于C的Condition是False,C被跳过,所以它的依赖链不会被触发,B也就不会运行。
- Target D(AfterTargets="C"):和BeforeTargets逻辑一致,只要C在目标列表里(哪怕被跳过),就会在C之后运行D,所以D会被执行。
你之前的误解在于认为DependsOnTargets和BeforeTargets的触发前提都是「Target执行前」,但实际上:
- Before/AfterTargets是基于目标是否被列入构建列表,和目标是否执行无关;
- DependsOnTargets是基于目标是否会实际执行,只有目标要跑的时候才会拉上依赖。
举个验证例子:如果把C的Condition改成'True',运行msbuild /target:C,你会看到执行顺序是A→B→C→D,这时候B就会被触发了。
内容的提问来源于stack exchange,提问作者aprelev
相关产品推荐
相关产品推荐

