MSBuild 条件
MSBuild 支持可在允许 Condition
属性的任何位置应用的特定条件集;请参阅 支持的元素。 下表说明了这些条件。
条件 | 描述 |
---|---|
'stringA ' == 'stringB ' |
如果 stringA 等于 stringB ,则计算结果为 true 。例如: Condition="'$(Configuration)'=='DEBUG'" 简单字母数字字符串或布尔值不需要单引号。 但是,空值需要单引号。 此检查不区分大小写。 |
'stringA' != 'stringB' |
如果 stringA 不等于 stringB ,则计算结果为 true 。例如: Condition="'$(Configuration)'!='DEBUG'" 简单字母数字字符串或布尔值不需要单引号。 但是,空值需要单引号。 此检查不区分大小写。 |
<、>、<=、>= | 计算操作数的数值。 如果关系评估为 true,则返回 true 。 操作数的计算结果必须为十进制或十六进制数或四部分虚线版本。 十六进制数字必须以 0x 开头。
注意: 在 XML 中,必须转义字符 < 和 > 。 符号 < 表示为 < 。 符号 > 表示为 > 。 |
Exists(“stringA ”) |
如果存在名称 stringA 的文件或文件夹,则计算结果为 true 。例如: Condition="!Exists('$(Folder)')" 简单字母数字字符串或布尔值不需要单引号。 但是,空值需要单引号。 此条件不会扩展通配符,如 * 。 |
HasTrailingSlash('stringA ') |
如果指定的字符串包含尾部后斜杠 (\) 或正斜杠 (/) 字符,则计算结果为 true 。例如: Condition="!HasTrailingSlash('$(OutputPath)')" 简单字母数字字符串或布尔值不需要单引号。 但是,空值需要单引号。 |
! | 如果操作数的计算结果为 false ,则计算结果为 true 。 |
And |
如果两个操作数的计算结果为 true ,则计算结果为 true 。 |
Or |
如果至少有一个操作数的计算结果为 true ,则计算结果为 true 。 |
() | 计算结果为 true 的分组机制(如果表达式包含在计算结果中为 true )。 |
$if$ ( %expression% ), $else$, $endif$ |
检查指定的 %expression% 是否与传递的自定义模板参数的字符串值匹配。 如果 $if$ 条件的计算结果为 true ,则运行其语句;否则,将检查 $else$ 条件。 如果 $else$ 条件 true ,则运行其语句;否则,$endif$ 条件将结束表达式计算。有关用法示例,请参阅 Visual Studio 项目/项模板参数逻辑。 |
Condition
元素是单个字符串,因此表达式中使用的任何字符串(包括属性值周围)都需要用单引号括起来。 允许运算符之间的空格,通常用于可读性,但它们不是必需的。
若要使用布尔 And
和 Or
运算符,请在 Condition
元素的字符串值中指定操作数,如以下示例所示:
Condition="'$(Configuration)' == 'Debug' And '$(MSBuildProjectExtension)' == '.csproj'"
可以链接布尔运算符。 运算符 And
优先级高于 Or
,但为了清楚起见,我们建议在使用多个布尔运算符时使用括号来明确计算顺序。 否则,MSBuild 会发出警告MSB4130。
可以在条件中使用字符串方法,如以下示例所示,其中 TrimEnd() 函数仅用于比较字符串的相关部分,以区分 .NET Framework 和 .NET Core 目标框架。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;net48;netstandard2.1;netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
<!-- Properties for .NET Framework -->
</PropertyGroup>
</Project>
在 MSBuild 项目文件中,没有真正的布尔类型。 布尔数据以可能为空或设置为任何值的属性表示。 因此,'$(Prop)' == 'true'
表示“如果 Prop 是 true
”,但 '$(Prop)' != 'false'
表示“如果 Prop 是 true
或未设置或设置为其他内容”。
布尔逻辑仅在条件上下文中计算,因此属性设置(如 <Prop2>'$(Prop1)' == 'true'</Prop>
)表示为字符串(在变量扩展后),不计算为布尔值。
MSBuild 实现一些特殊的处理规则,以便更轻松地使用用作布尔值的字符串属性。 接受布尔文本,因此 Condition="true"
和 Condition="false"
按预期工作。 MSBuild 还包含用于支持布尔求反运算符的特殊规则。 因此,如果 $(Prop)
为“true”,则 !$(Prop)
扩展为 !true
,并且此值与 false
进行比较,如预期的那样。
比较版本
关系运算符 <
、>
、<=
和 >=
支持由 System.Version分析的版本,以便可以比较具有四个数值部分的版本。 例如,'1.2.3.4' < '1.10.0.0'
true
。
谨慎
当一个或两个版本未指定所有四个部分时,System.Version
比较可能会产生令人惊讶的结果。 例如,版本 1.1 早于版本 1.1.0。
MSBuild 提供 属性函数来比较具有与语义版本控制(semver)兼容的不同规则集的版本。
条件中的扩展
根据项目文件中的位置,可以对属性($)、项列表(@)和项元数据(%)使用扩展。 扩展取决于 MSBuild 如何处理项目文件 。
性能
计算并转换为属性值,其中包含表达式(如 $(SomeProperty)
)的条件。 如果条件不在目标之外,则表达式将在项目文件的计算过程中计算。 属性的值取决于展开所有导入后项目文件中的位置。 如果条件位于目标中,则当目标执行时会对其进行评估,并且该值受执行生成期间发生的任何更改的影响。
在展开的项目文件中未定义的属性,其中条件表达式的计算结果为空字符串,没有任何诊断错误或警告。
项列表
包含 @-expression(如 @(SomeItems)
)的条件在顶级和目标的项目组中展开。
项可以依赖于任何属性,并且可以依赖于已按顺序定义的项。
原因是 MSBuild 在多个传递中处理项目文件。 项评估传递在初始属性计算和导入扩展传递之后发生。 因此,在开始定义项后计算的任何条件中,都允许 @-expression。 也就是说,在项、项组和目标中。
元数据
包含元数据表达式(如 %(ItemMetadata)
)的条件在与项列表相同的上下文中展开,即顶级和目标项组中的项组中。 但是,扩展在项组中可能有不同的行为,具体取决于项组是位于目标外部还是目标内部。 此外,对于各种形式的元数据表达式,%(ItemName.MetadataName)
、%(JustTheMetadataName)
和 @(ItemName->'%(MetadataName)')
,仅允许项转换(最后一个)在目标之外。 目标中的 %-expression 的值在运行时计算,具体取决于目标执行期间的任何状态更改。 目标的执行及其中包含的任何 %表达式的值也取决于目标的批处理,还可以触发批处理;请参阅 MSBuild 批处理。
支持的元素
以下元素支持 Condition
属性:
- 进口
- ImportGroup
- 项目
- ItemDefinitionGroup
- ItemGroup
- ItemMetadata
- OnError
- 输出
- 财产
- PropertyGroup
- 目标
- 任务
- UsingTask
- 什么时候