属性函数是对 MSBuild 属性定义中显示的 .NET 方法的调用。 通常使用它们来构造需要更复杂的逻辑的属性定义。
与任务不同,属性函数可以在目标外部使用。 每当展开属性或项时,都会计算属性函数。 因此,对于任何目标之外的属性和项,将在任何目标运行之前评估属性函数。 对于目标中的属性组和项组,在执行目标时会评估属性函数。
如果不使用 MSBuild 任务,可以读取系统时间、比较字符串、匹配正则表达式,并在生成脚本中执行其他作。 MSBuild 尝试将字符串转换为数字和数字转换为字符串,并根据需要进行其他转换。
从属性函数返回的字符串值已转义特殊字符。 如果要将这些值视为如同直接置于项目文件中,请使用 $([MSBuild]::Unescape()) 取消转义特殊字符。
属性函数语法
有三种类型的属性函数:每种类型都有不同的语法:
- String (instance) 属性函数
- 静态属性函数
- MSBuild 属性函数
字符串属性函数
所有生成属性值只是字符串值。 可以使用字符串(实例)方法对任何属性值进行操作。 例如,可以使用以下代码从表示完整路径的生成属性中提取驱动器名称(前三个字符):
$(ProjectOutputFolder.Substring(0,3))
静态属性函数
在生成脚本中,可以访问许多系统类的静态属性和方法。 若要获取静态属性的值,请使用以下语法,其中系统 Class 类的名称是 Property 属性的名称。
$([Class]::Property)
例如,可以使用以下代码将生成属性设置为当前日期和时间。
<Today>$([System.DateTime]::Now)</Today>
若要调用静态方法,请使用以下语法,其中 Class 系统类 Method 的名称是方法的名称,并且 (Parameters) 是方法的参数列表:
$([Class]::Method(Parameters))
例如,若要将生成属性设置为新的 GUID,可以使用以下脚本:
<NewGuid>$([System.Guid]::NewGuid())</NewGuid>
对于重载的方法,MSBuild 会尝试查找具有匹配参数的方法。
在 MSBuild 17.14 及更高版本中,可以使用参数语法 out _ 指定 out 参数。 请参阅 参考参数。 忽略 out 参数值。 例如:
<IsInteger>$([System.Int32]::TryParse("123", out _))</IsInteger>
该属性 IsInteger 是 true ,如果输入成功解析为整数,但忽略已分析的值。
在静态属性函数中,可以将 .NET Standard 2.0 中定义的任何公共静态方法或属性用于以下系统类:
- System.Byte
- System.Char
- System.Convert
- System.DateTime
- System.DateTimeOffset (在 MSBuild 17.3 及更高版本中可用)
- System.Decimal
- System.Double
- System.Enum
- System.Guid
- System.Int16
- System.Int32
- System.Int64
- System.IO.Path
- System.Math
- System.Runtime.InteropServices.OSPlatform
- System.Runtime.InteropServices.RuntimeInformation
- System.UInt16
- System.UInt32
- System.UInt64
- System.SByte
- System.Single
- System.String
- System.StringComparer
- System.TimeSpan
- System.Text.RegularExpressions.Regex
- System.UriBuilder
- System.Version
- Microsoft.Build.Utilities.ToolLocationHelper
注释
在支持 MSBuild 的环境中使用 MSBuild 时,在 .NET Standard 2.0 中未定义的方法和属性可能可用,但不能保证在所有情况下都可用。 出于兼容性原因,最好避免这样做。
此外,可以使用以下静态方法和属性:
- System.Environment::CommandLine
- System.Environment::ExpandEnvironmentVariables
- System.Environment::GetEnvironmentVariable
- System.Environment::GetEnvironmentVariables
- System.Environment::GetFolderPath
- System.Environment::GetLogicalDrives
- System.Environment::Is64BitOperatingSystem
- System.Environment::Is64BitProcess
- System.Environment::MachineName
- System.Environment::NewLine
- System.Environment::OSVersion
- System.Environment::ProcessorCount
- System.Environment::StackTrace
- System.Environment::SystemDirectory
- System.Environment::SystemPageSize
- System.Environment::TickCount
- System.Environment::UserDomainName
- System.Environment::UserInteractive
- System.Environment::UserName
- System.Environment::Version
- System.Environment::WorkingSet
- System.IO.Directory::GetDirectories
- System.IO.Directory::GetFiles
- System.IO.Directory::GetLastAccessTime
- System.IO.Directory::GetLastWriteTime
- System.IO.Directory::GetParent
- System.IO.File::Exists
- System.IO.File::GetAttributes
- System.IO.File::GetCreationTime
- System.IO.File::GetLastAccessTime
- System.IO.File::GetLastWriteTime
- System.IO.File::ReadAllText
- System.Globalization.CultureInfo::GetCultureInfo
- System.Globalization.CultureInfo::new
- System.Globalization.CultureInfo::CurrentUICulture
System.OperatingSystem 属性函数
属性 System.OperatingSystem 函数返回有关 MSBuild 所运行的操作系统的信息。 例如,如果你的项目面向 Linux 并在 macOS 上生成它,则属性函数将返回有关 macOS 的信息。
在 .NET 上运行的 dotnet build MSBuild 中,System.OperatingSystem类的所有静态方法都可以作为静态属性函数调用。
在 .NET Framework (MSBuild.exe) 上运行的 MSBuild 中,只有 System.OperatingSystem 的以下方法可作为静态属性函数进行调用。 MSBuild 在内部实现它们,因为 System.OperatingSystem 不会在 .NET Framework 上定义它们。 没有 .NET SDK 的操作系统,其方法(例如 System.OperatingSystem::IsTvOS)是不可调用的。
- System.OperatingSystem::IsOSPlatform
- System.OperatingSystem::IsOSPlatformVersionAtLeast
- System.OperatingSystem::IsLinux
- System.OperatingSystem::IsFreeBSD
- System.OperatingSystem::IsFreeBSDVersionAtLeast
- System.OperatingSystem::IsMacOS
- System.OperatingSystem::IsMacOSVersionAtLeast
- System.OperatingSystem::IsWindows
- System.OperatingSystem::IsWindowsVersionAtLeast
以下示例显示了这些属性函数的用法。
<IsWindows>$([System.OperatingSystem]::IsWindows())</IsWindows>
对静态属性调用实例方法
如果访问返回对象实例的静态属性,则可以调用该对象的实例方法。 若要调用实例方法,请使用以下语法,其中 Class 系统类的名称是属性的名称, PropertyMethod 是方法的名称,是 (Parameters) 方法的参数列表:
$([Class]::Property.Method(Parameters))
类名必须使用命名空间进行完整限定。
例如,可以使用以下代码将生成属性设置为当前日期。
<Today>$([System.DateTime]::Now.ToString('yyyy.MM.dd'))</Today>
MSBuild 属性函数
在您的项目构建中,有若干静态方法可访问,以便于提供算术、按位逻辑和转义字符的支持。 使用以下语法访问这些方法,其中方法 Method 的名称是 (Parameters) 该方法的参数列表。
$([MSBuild]::Method(Parameters))
例如,若要将具有数值的两个属性相加,请使用以下代码。
$([MSBuild]::Add($(NumberOne), $(NumberTwo)))
下面是 MSBuild 属性函数的列表:
| 函数签名 | DESCRIPTION |
|---|---|
double Add(double a, double b) |
将两个双精度型值相加。 |
long Add(long a, long b) |
将两个长型值相加。 |
int BitwiseOr(int first, int second) |
对第一个值和第二个值执行按位 OR(第一个值 | 第二个值)。 |
int BitwiseAnd(int first, int second) |
对第一个值和第二个值执行按位 AND(第一个值 & 第二个值)。 |
int BitwiseXor(int first, int second) |
对第一个值和第二个值执行按位 XOR(第一个值 ^ 第二个值)。 |
int BitwiseNot(int first) |
执行按位 NOT(~第一个值)。 |
string CheckFeatureAvailability(string featureName) |
仅当此版本的 MSBuild 中支持指定功能时,才以字符串形式返回功能名称。 |
string ConvertToBase64(string toEncode) |
将所有字节转换为 Base64(字母数字字符加 + 和 /),最后以一个或两个 = 结尾,然后返回字符串。 |
string ConvertFromBase64(string toDecode) |
从 base 64 转换(字母数字字符加 + 和 /)后返回字符串,以一个或两个 = 结尾。 |
double Divide(double a, double b) |
将两个双精度型值相除。 |
long Divide(long a, long b) |
将两个长型值相除。 |
bool DoesTaskHostExist(string runtime, string architecture) |
返回当前是否已为指定的运行时和体系结构值安装任务主机。 请参阅 MSBuild DoesTaskHostExist。 |
string Escape(string unescaped) |
根据 MSBuild 转义规则对字符串进行转义。 |
string EnsureTrailingSlash(string path) |
如果给定路径没有尾部斜杠,请添加一个。 如果路径为空字符串,则不对其进行修改。 请参阅 MSBuild EnsureTrailingSlash。 |
string FilterTargetFrameworks(string incoming, string filter) |
返回与指定筛选器匹配的目标框架的列表。 如果目标框架 incoming 与 filter 上的任何所需目标框架匹配,则保留该目标框架。 请参阅 MSBuild TargetFramework 和 TargetPlatform 函数。 |
string GetCurrentToolsDirectory() |
获取当前的 MSBuild 工具目录。 |
string GetMSBuildExtensionsPath() |
获取 MSBuild 扩展路径。 运行MSBuild.exe时,这通常是 MSBuild 可执行文件文件夹。 在 Visual Studio 中运行时,这是 Visual Studio 安装文件夹下的 MSBuild 子文件夹。 |
string GetMSBuildSDKsPath() |
获取当前 MSBuild 实例预期 SDK 所在的目录。 |
string GetProgramFiles32() |
获取通常安装 32 位软件包的文件系统根文件夹。 例如,C:\Program Files (x86)。 |
string GetTargetFrameworkIdentifier(string targetFramework) |
从 TargetFramework 分析 TargetFrameworkIdentifier。 请参阅 MSBuild TargetFramework 和 TargetPlatform 函数。 |
string GetTargetFrameworkVersion(string targetFramework, int versionPartCount) |
从 TargetFramework 分析 TargetFrameworkVersion。 请参阅 MSBuild TargetFramework 和 TargetPlatform 函数。 |
string GetTargetPlatformIdentifier(string targetFramework) |
从 TargetFramework 分析 TargetPlatformIdentifier。 请参阅 MSBuild TargetFramework 和 TargetPlatform 函数。 |
string GetTargetPlatformVersion(string targetFramework, int versionPartCount) |
从 TargetFramework 分析 TargetPlatformVersion。 请参阅 MSBuild TargetFramework 和 TargetPlatform 函数。 |
string GetToolsDirectory32() |
获取 MSBuild 工具的 32 位版本的目录。 |
string GetToolsDirectory64() |
获取 MSBuild 工具的 64 位版本的目录。 |
string GetDirectoryNameOfFileAbove(string startingDirectory, string fileName) |
在指定目录或该目录上方的目录结构中找到并返回文件所在的目录。 请参阅 MSBuild GetDirectoryNameOfFileAbove。 |
string GetPathOfFileAbove(string file, string startingDirectory) |
在当前生成文件位置所在及上级的目录结构中搜索并返回文件的完整路径,如果指定,则基于 startingDirectory。 请参阅 MSBuild GetPathOfFileAbove。 |
object GetRegistryValue(string keyName, string valueName, object defaultValue) |
获取注册表项和值的值。 请参阅 MSBuild GetRegistryValue。 |
object GetRegistryValueFromView(string keyName, string valueName, object defaultValue, params object[] views) |
给定注册表项、值以及一个或多个有序注册表视图时,获取系统注册表数据。 请参阅 MSBuild GetRegistryValueFromView。 |
string GetVsInstallRoot() |
获取与 MSBuild 的当前实例关联的 Visual Studio 安装文件夹根目录的完整路径。 |
bool IsOsPlatform(string platformString) |
指定当前 OS 平台是否为 platformString。
platformString 必须是 OSPlatform 的一个成员。 |
bool IsOsBsdLike() |
如此 如果当前 OS 是 BSD 样式的 Unix 系统。 |
bool IsOSUnixLike() |
如此 如果当前 OS 是 Unix 系统。 |
bool IsTargetFrameworkCompatible(string targetFrameworkTarget, string targetFrameworkCandidate) |
如果候选目标框架(第二个参数)与第一个参数指示的目标框架兼容,则返回“True”;否则返回 false。 请参阅 MSBuild TargetFramework 和 TargetPlatform 函数。 |
int LeftShift(int operand, int count) |
向左移位 count 位。 MSBuild 17.7 及更高版本。 |
string MakeRelative(string basePath, string path) |
将 path 关联到 basePath。
basePath 必须是绝对目录。 如果无法关联 path,则会返回逐字字符串。 类似于 Uri.MakeRelativeUri。 请参阅 MSBuild MakeRelative。 |
double Modulo(double a, double b) |
对两个双精度型值取模。 |
long Modulo(long a, long b) |
对两个长型值取模。 |
double Multiply(double a, double b) |
将两个双精度型值相乘。 |
long Multiply(long a, long b) |
将两个长型值相乘。 |
string NormalizeDirectory(params string[] path) |
获取所提供目录的规范化完整路径,确保其包含当前操作系统的正确目录分隔符,并且保证路径末尾有一个斜杠。 |
string NormalizePath(params string[] path) |
获取所提供路径的规范化完整路径,并确保它包含当前操作系统的正确目录分隔符。 |
int RightShift(int operand, int count) |
以带符号整数的形式向右移位 count 位。 MSBuild 17.7 及更高版本。 |
int RightShiftUnsigned(int operand, int count) |
向右移位 count 位,将操作数视为无符号整数。 MSBuild 17.7 及更高版本。 |
object StableStringHash(string toHash, StringHashingAlgorithm algo) |
接受字符串参数,并返回保证稳定哈希代码。 请参阅 MSBuild StableStringHash。 |
string SubstringByAsciiChars(string input, int start, int length) |
返回 input 的子字符串,从指定的 start 位置开始并具有指定的 length,其中将字符串视为 ASCII 编码。 |
double Subtract(double a, double b) |
将两个双精度型值相减。 |
long Subtract(long a, long b) |
将两个长型值相减。 |
string Unescape(string escaped) |
根据 MSBuild 转义规则取消对字符串进行转义。 |
string ValueOrDefault(string conditionValue, string defaultValue) |
仅当参数defaultValue为空时返回参数conditionValue中的字符串,否则返回值conditionValue。 请参阅 MSBuild ValueOrDefault。 |
bool VersionEquals(string a, string b) |
如果版本true和a根据以下规则等同,则返回b。 请参阅 MSBuild 版本比较函数。 |
bool VersionGreaterThan(string a, string b) |
如果版本true大于a以下规则,则返回b。 请参阅 MSBuild 版本比较函数。 |
bool VersionGreaterThanOrEquals(string a, string b) |
如果版本true大于或等于a以下规则,则返回b。 请参阅 MSBuild 版本比较函数。 |
bool VersionLessThan(string a, string b) |
如果版本true低于a以下规则,则返回b。 请参阅 MSBuild 版本比较函数。 |
bool VersionLessThanOrEquals(string a, string b) |
如果版本true小于或等于a以下规则,则返回b。 请参阅 MSBuild 版本比较函数。 |
bool VersionNotEquals(string a, string b) |
如果版本false和a根据以下规则等同,则返回b。 请参阅 MSBuild 版本比较函数。 |
嵌套属性函数
可以组合属性函数以形成更复杂的函数,如以下示例所示:
$([MSBuild]::BitwiseAnd(32, $([System.IO.File]::GetAttributes(tempFile))))
此示例返回值 FileAttributes。 路径 Archive 提供的文件的 tempFile 位(32 或 0)。 请注意,枚举的数据值在某些上下文中不能按名称显示。 在前面的示例中,必须改用数值(32)。 在其他情况下,必须使用枚举数据值,这具体取决于所调用方法的要求。 在下面的示例中,必须使用枚举值 RegexOptions.,必须使用 ECMAScript,因为无法按照该方法所期望的方式转换数值。
<PropertyGroup>
<GitVersionHeightWithOffset>$([System.Text.RegularExpressions.Regex]::Replace("$(PrereleaseVersion)", "^.*?(\d+)$", "$1", "System.Text.RegularExpressions.RegexOptions.ECMAScript"))</GitVersionHeightWithOffset>
</PropertyGroup>
元数据也可能出现在嵌套属性函数中。 有关详细信息,请参阅批处理。
MSBuild DoesTaskHostExist
MSBuild 中的 DoesTaskHostExist 属性函数将返回当前是否针对特定运行时和体系结构值安装了任务宿主。
此属性函数具有以下语法:
$([MSBuild]::DoesTaskHostExist(string theRuntime, string theArchitecture))
MSBuild EnsureTrailingSlash
如果尚不存在尾部反斜杠,MSBuild 中的 EnsureTrailingSlash 属性函数将添加一条。
此属性函数具有以下语法:
$([MSBuild]::EnsureTrailingSlash('$(PathProperty)'))
MSBuild GetDirectoryNameOfFileAbove
MSBuild GetDirectoryNameOfFileAbove 属性函数向上搜索包含指定文件的目录,从指定目录开始(包括指定目录)。 如果找到该文件,则返回最接近的目录的完整路径,否则返回一个空字符串。
此属性函数具有以下语法:
$([MSBuild]::GetDirectoryNameOfFileAbove(string startingDirectory, string fileName))
此示例演示了如何在当前文件夹中或更高一级中导入最近的 EnlistmentInfo.props 文件(仅当找到匹配项时):
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), EnlistmentInfo.props))' != '' " />
使用 GetPathOfFileAbove 函数可以使此示例编写得更简洁。
<Import Project="$([MSBuild]::GetPathOfFileAbove(EnlistmentInfo.props))" Condition=" '$([MSBuild]::GetPathOfFileAbove(EnlistmentInfo.props))' != '' " />
MSBuild GetPathOfFileAbove
MSBuild GetPathOfFileAbove 属性函数向上搜索包含指定文件的目录,从指定目录开始(包括指定目录)。 如果找到最接近的匹配文件,它将返回完整路径,否则返回空字符串。
此属性函数具有以下语法:
$([MSBuild]::GetPathOfFileAbove(string file, [string startingDirectory]))
其中 file 要搜索的文件的名称,是 startingDirectory 启动搜索的可选目录。 默认情况下,搜索从当前文件自己的目录中开始。
此示例演示如何仅当找到匹配项时,才能在当前目录中或上方导入名为 dir.props 的文件:
<Import Project="$([MSBuild]::GetPathOfFileAbove(dir.props))" Condition=" '$([MSBuild]::GetPathOfFileAbove(dir.props))' != '' " />
这在功能上等效于
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))' != '' " />
但是,有时需要在父目录中启动搜索,以避免匹配当前文件。 此示例演示 Directory.Build.props 文件如何在树的更高级别中导入最近的 Directory.Build.props 文件,而无需递归导入自身:
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
这在功能上等效于
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove('$(MSBuildThisFileDirectory)../', 'Directory.Build.props'))/Directory.Build.props" />
MSBuild GetRegistryValue(获取注册表值)
MSBuild GetRegistryValue 属性函数返回注册表项的值。 此函数采用两个参数:键名称和值名称,并从注册表返回值。 如果未指定值名称,则返回默认值。
以下示例演示如何使用此函数:
$([MSBuild]::GetRegistryValue(`HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0\Debugger`, ``)) // default value
$([MSBuild]::GetRegistryValue(`HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0\Debugger`, `SymbolCacheDir`))
$([MSBuild]::GetRegistryValue(`HKEY_LOCAL_MACHINE\SOFTWARE\(SampleName)`, `(SampleValue)`)) // parens in name and value
警告
在 MSBuild 的 .NET SDK 版本中,dotnet build不支持此函数。
MSBuild 从视图中获取注册表值
MSBuild GetRegistryValueFromView 属性函数在给定注册表项、值和一个或多个排序的注册表视图的情况下获取系统注册表数据。 按顺序在每个注册表视图中搜索键和值,直到找到为止。
此属性函数的语法为:
[MSBuild]::GetRegistryValueFromView(string keyName, string valueName, object defaultValue, params object[] views)
Windows 64 位操作系统维护HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node 注册表项,该注册表项为 32 位应用程序提供HKEY_LOCAL_MACHINE\SOFTWARE 注册表视图。
默认情况下,WOW64 上运行的 32 位应用程序访问 32 位注册表视图,64 位应用程序访问 64 位注册表视图。
以下注册表视图可用:
| 注册表视图 | 定义 |
|---|---|
| RegistryView.Registry32 | 32 位应用程序注册表视图。 |
| RegistryView.Registry64 | 64 位应用程序注册表视图。 |
| RegistryView.Default | 与应用程序正在运行的进程匹配的注册表视图。 |
下面是一个示例。
$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Silverlight\v3.0\ReferenceAssemblies', 'SLRuntimeInstallPath', null, RegistryView.Registry64, RegistryView.Registry32))
前面的代码获取 ReferenceAssemblies 键的 SLRuntimeInstallPath 数据,先在 64 位注册表视图中查找,然后在 32 位注册表视图中查找。
警告
在 MSBuild 的 .NET SDK 版本中,dotnet build不支持此函数。
MSBuild MakeRelative
MSBuild MakeRelative 属性函数返回相对于第一个路径的第二个路径的相对路径。 每个路径可以是文件或文件夹。
此属性函数具有以下语法:
$([MSBuild]::MakeRelative($(FileOrFolderPath1), $(FileOrFolderPath2)))
以下代码是此语法的示例。
<PropertyGroup>
<Path1>c:\users\</Path1>
<Path2>c:\users\username\</Path2>
</PropertyGroup>
<Target Name = "Go">
<Message Text ="$([MSBuild]::MakeRelative($(Path1), $(Path2)))" />
<Message Text ="$([MSBuild]::MakeRelative($(Path2), $(Path1)))" />
</Target>
<!--
Output:
username\
..\
-->
MSBuild StableStringHash
MSBuild StableStringHash 属性函数接受字符串参数,并返回一个保证稳定哈希代码,这意味着始终为同一字符串输入返回相同的代码。 无论是使用 MSBuild 还是 dotnet build,返回的哈希值都是相同的,并且在跨平台架构中保持稳定,这一点不同于 .NET 方法 GetHashCode。 不能保证在不同的 MSBuild 版本中保持稳定。
此函数在 MSBuild 16.9.0 或更高版本中可用。
以下示例演示了如何使用此函数。
<Project>
<PropertyGroup>
<MyHash>$([MSBuild]::StableStringHash("test1"))</MyHash>
</PropertyGroup>
<Target Name="WriteHash" AfterTargets="Build">
<Message Text="Hash: $(MyHash)"/>
</Target>
</Project>
对于 MSBuild 版本 17.10 及更高版本,此函数接受第二个可选参数,请求使用哈希算法:
<Project>
<PropertyGroup>
<MyHash>$([MSBuild]::StableStringHash("test1", "Sha256"))</MyHash>
</PropertyGroup>
<Target Name="WriteHash" AfterTargets="Build">
<Message Text="Hash: $(MyHash)"/>
</Target>
</Project>
第二个参数不区分大小写,当前支持以下值:
- 旧版 - 保留与在没有第二个参数的情况下调用函数相同的行为。 返回带符号的 32 位整数,其属性与
string.GetHashCode相似。 - Fnv1a32bit - 返回表示给定字符串的 Fowler–Noll–Vo 版本“1a”哈希的有符号32位整数。
- Fnv1a64bit - 返回带符号的 64 位整数,此整数表示给定字符串的版本“1a”的 Fowler–Noll–Vo 哈希。
- Sha256 - 返回一个表示给定字符串的 SHA256 哈希的无前缀十六进制字符串。
MSBuild ValueOrDefault
MSBuild ValueOrDefault 属性函数返回第一个参数,除非它为 null 或为空。 如果第一个参数为 null 或为空,则该函数返回第二个参数。
以下示例演示了如何使用此函数。
<Project>
<PropertyGroup>
<Value1>$([MSBuild]::ValueOrDefault('$(UndefinedValue)', 'a'))</Value1>
<Value2>$([MSBuild]::ValueOrDefault('b', '$(Value1)'))</Value2>
</PropertyGroup>
<Target Name="MyTarget">
<Message Text="Value1 = $(Value1)" />
<Message Text="Value2 = $(Value2)" />
</Target>
</Project>
<!--
Output:
Value1 = a
Value2 = b
-->
MSBuild TargetFramework 和 TargetPlatform 函数
MSBuild 16.7 及更高版本定义了多个用于处理 TargetFramework 和 TargetPlatform 属性的函数。
| 函数签名 | DESCRIPTION |
|---|---|
FilterTargetFrameworks(string incoming, string filter) |
返回与指定筛选器匹配的目标框架的列表。 如果目标框架 incoming 与 filter 上的任何所需目标框架匹配,则保留该目标框架。 |
GetTargetFrameworkIdentifier(string targetFramework) |
从 TargetFramework 分析 TargetFrameworkIdentifier。 |
GetTargetFrameworkVersion(string targetFramework, int versionPartCount) |
从 TargetFramework 分析 TargetFrameworkVersion。 |
GetTargetPlatformIdentifier(string targetFramework) |
从 TargetFramework 分析 TargetPlatformIdentifier。 |
GetTargetPlatformVersion(string targetFramework, int versionPartCount) |
从 TargetFramework 分析 TargetPlatformVersion。 |
IsTargetFrameworkCompatible(string targetFrameworkTarget, string targetFrameworkCandidate) |
如果候选目标框架(第二个参数)与第一个参数指示的目标框架兼容,则返回 true;否则返回 false。 |
versionPartCount与GetTargetFrameworkVersion的GetTargetPlatformVersion参数默认值为 2。
以下示例演示如何使用这些函数。
<Project>
<PropertyGroup>
<Value1>$([MSBuild]::GetTargetFrameworkIdentifier('net5.0-windows7.0'))</Value1>
<Value2>$([MSBuild]::GetTargetFrameworkVersion('net5.0-windows7.0'))</Value2>
<Value3>$([MSBuild]::GetTargetPlatformIdentifier('net5.0-windows7.0'))</Value3>
<Value4>$([MSBuild]::GetTargetPlatformVersion('net5.0-windows7.0'))</Value4>
<Value5>$([MSBuild]::IsTargetFrameworkCompatible('net5.0-windows', 'net5.0'))</Value5>
<Value6>$([MSBuild]::IsTargetFrameworkCompatible('net5.0', 'net6.0'))</Value6>
<Value7>$([MSBuild]::IsTargetFrameworkCompatible('net5.0', 'net8.0'))</Value7>
<Value8>$([MSBuild]::IsTargetFrameworkCompatible('net8.0', 'net6.0'))</Value8>
</PropertyGroup>
<Target Name="MyTarget">
<Message Text="Value1 = $(Value1)" />
<Message Text="Value2 = $(Value2)" />
<Message Text="Value3 = $(Value3)" />
<Message Text="Value4 = $(Value4)" />
<Message Text="Value5 = $(Value5)" />
<Message Text="Value6 = $(Value6)" />
<Message Text="Value7 = $(Value7)" />
<Message Text="Value8 = $(Value8)" />
</Target>
</Project>
Value1 = .NETCoreApp
Value2 = 5.0
Value3 = windows
Value4 = 7.0
Value5 = True
Value6 = False
Value7 = False
Value8 = True
MSBuild FilterTargetFrameworks (过滤目标框架)
使用 MSBuild 17.6 和更高版本(或 .NET 7 和更高版本),可以使用此属性函数从目标框架名字对象 (TFM) 列表中选择一个子集,以将列表限制为仅包含在给定筛选器参数的情况下与 TFM 列表匹配的框架。
例如,如果 incoming 为 net6.0;net7.0;netstandard2.0 且 filter 为 net7.0;netstandard2.0,则结果为 net7.0;netstandard2.0。
MSBuild 版本比较函数
MSBuild 16.5 及更高版本定义了多个函数,用于比较表示版本的字符串。
注释
条件中的比较运算符 可以比较可分析为 System.Version 对象的字符串,但比较可能会产生意外的结果。 首选属性函数。
| 函数签名 | DESCRIPTION |
|---|---|
VersionEquals(string a, string b) |
如果版本true和a根据以下规则等同,则返回b。 |
VersionGreaterThan(string a, string b) |
如果版本true大于a以下规则,则返回b。 |
VersionGreaterThanOrEquals(string a, string b) |
如果版本true大于或等于a以下规则,则返回b。 |
VersionLessThan(string a, string b) |
如果版本true低于a以下规则,则返回b。 |
VersionLessThanOrEquals(string a, string b) |
如果版本true小于或等于a以下规则,则返回b。 |
VersionNotEquals(string a, string b) |
如果版本false和a根据以下规则等同,则返回b。 |
在这些方法中,版本分析方式如下 System.Version,但有以下例外情况:
忽略前导
v或V,这允许对$(TargetFrameworkVersion)进行比较。忽略从第一个“-”或“+”到版本字符串末尾的所有内容。 虽然顺序与 SemVer 不同,但允许传递语义版本 (SemVer)。 相反,预发行版说明符和生成元数据没有任何排序权重。 例如,这在为
>= x.y启用功能并使其在x.y.z-pre生效时可能非常有用。未指定的部分与零值部分相同。 (
x == x.0 == x.0.0 == x.0.0.0)。整数组件中不允许空格。
主版本仅有效(
3等于3.0.0.0)+不允许作为整数部分中的正号(它被视为 semver 元数据并被忽略)
小窍门
TargetFramework 属性的比较通常应使用 IsTargetFrameworkCompatible,而不是提取和比较版本。 这允许比较在 TargetFramework 和版本中不同的 TargetFrameworkIdentifier。
MSBuild 条件函数
函数 Exists 和 HasTrailingSlash 不是属性函数。 它们可用于属性 Condition 。 请参阅 MSBuild 条件。