虽然测试属性值(或缺少属性值)是在 MSBuild 中完成几乎所有事情的方式,但有时还有其他方法。
如何知道当前的MSBuild项目是否为SDK项目?
换句话说:
- 给定一个 XML 文件...
- 其完整路径在
MSBuildProjectFullPath well-known property...
- 并且其第一个标签是
Project...
- 该标签是否有
Sdk 属性?
感谢 MSBuild 的property functions,您可以执行以下操作:
- 使用
[System.IO.File]::ReadAllText以字符串形式读取项目文件的内容;
- 然后使用
[System.Text.RegularExpressions.Regex]::IsMatch 测试带有Sdk 属性的Project 标记。
<_projectcontents>$([System.IO.File]::ReadAllText(`$(MSBuildProjectFullPath)`))<_sdkregex>(?s-i)(^|\s|>)<Project\s(([^>]*?)\s)?Sdk(\s*?)=(\s*?)" <_issdkproject>$([System.Text.RegularExpressions.Regex]::IsMatch(`$(_ProjectContents)`, `$(_SdkRegex)`))
或者,如果您更喜欢单线:
<PropertyGroup>
<_IsSdkProject>$([System.Text.RegularExpressions.Regex]::IsMatch(`$([System.IO.File]::ReadAllText(`$(MSBuildProjectFullPath)`))`, `(?s-i)(^|\s|>)<Project\s(([^>]*?)\s)?Sdk(\s*?)=(\s*?)"`))</_IsSdkProject>
</PropertyGroup>
然后您可以在Condition 中使用_IsSdkProject 的值,即True 或False,如下所示:
<PropertyGroup Condition="'$(_IsSdkProject)'=='True'">
<SomeProperty>SomeValue</SomeProperty>
</PropertyGroup>
正则表达式解释
在上述正则表达式中,&lt; 和 &gt; 字符已替换为 XML 实体(分别为&lt; 和 &gt;)。原来的正则表达式如下:
(?s-i)(^|\s|>)<Project\s(([^>]*?)\s)?Sdk(\s*?)=(\s*?)"
这意味着:
- 在single-line, case-sensitive mode...
- 无论是在文件的开头,还是跟在一个空白字符之后,或者跟在一个
&gt; 字符之后...
- 找到文字字符串
<Project...
- 然后是一个空格字符...
- 然后,可选地,除
&gt; 和另一个空白字符之外的任意数量的任意字符...
- 然后是文字字符串
Sdk...
- 然后,可以选择任意数量的空白字符...
- 然后是字符
=...
- 然后,可以选择任意数量的空白字符...
- 然后是字符
"
on regex101.com 是一个更好的解释,以及一个在线测试器,您可以在其中插入项目文件的内容并实时测试。该网站是为 Javascript 正则表达式创建的,它的行为与 .NET 中的完全一样,但它仍然很有用。