屬性函式
屬性函式是 MSBuild 屬性定義中顯示的 .NET Framework 方法呼叫。 不同于工作,屬性函式可以在目標之外使用。 每當屬性或專案展開時,就會評估屬性或專案,這是在任何目標以外的屬性和專案執行之前,或是評估目標時,針對目標內的屬性群組和專案群組進行評估。
在不使用 MSBuild 工作的情況下,您可以讀取系統時間、比較字串、比對規則運算式,以及執行組建指令碼中的其他動作。 MSBuild 會嘗試將字串轉換為數字或將數字轉換為字串,並視需要進行其他轉換。
從屬性函式傳回的字串值具有逸出的特殊字元。 如果您想要將值視為直接放入專案檔中,請使用 $([MSBuild]::Unescape())
來取消逸出特殊字元。
屬性函式適用于 .NET Framework 4 和更新版本。
屬性函式語法
以下是三種類型的屬性函式;每一種函式都具有不同的語法:
- 字串 (執行個體) 屬性函式
- 靜態屬性函式
- 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>
在靜態屬性函式中,您可以使用以下系統類別的靜態方法或屬性:
- System.Byte
- System.Char
- System.Convert
- System.DateTime
- 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
此外,您可以使用下列靜態方法和屬性:
- System.Environment::CommandLine
- System.Environment::ExpandEnvironmentVariables
- System.Environment::GetEnvironmentVariable
- System.Environment::GetEnvironmentVariables
- System.Environment::GetFolderPath
- System.Environment::GetLogicalDrives
- 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::GetCreationTime
- System.IO.File::GetAttributes
- System.IO.File::GetLastAccessTime
- System.IO.File::GetLastWriteTime
- System.IO.File::ReadAllText
在靜態屬性上呼叫執行個體方法
如果您存取的靜態屬性傳回物件執行個體,您就可以叫用該物件的執行個體方法。 若要叫用實例方法,請使用下列語法,其中 < Class > 是系統類別的名稱、 < Property > 是屬性的名稱、 < Method > 是方法的名稱,而 (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) | 將兩個長整數相加。 |
double Add(double a, double b) | 將兩個雙精度浮點數相減。 |
long Add(long a, long b) | 將兩個長整數相減。 |
double Add(double a, double b) | 將兩個雙精度浮點數相乘。 |
long Multiply(long a, long b) | 將兩個長整數相乘。 |
double Divide(double a, double b) | 將兩個雙精度浮點數相除。 |
long Divide(long a, long b) | 將兩個長整數相除。 |
double Modulo(double a, double b) | 對兩個雙精度浮點數進行模數運算。 |
long Modulo(long a, long b) | 對兩個長整數進行模數運算。 |
string Escape(string unescaped) | 根據 MSBuild 逸出規則逸出字串。 |
string Unescape(string escaped) | 根據 MSBuild 逸出規則取消逸出字串。 |
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 (~第一)。 |
bool IsOsPlatform(string platformString) | 指定目前的作業系統平台是否為 platformString 。 platformString 必須是 OSPlatform 的成員。 |
bool IsOSUnixLike() | 如果目前的作業系統是 UNIX 系統,則為 true。 |
string NormalizePath(params string[] path) | 取得所提供路徑的規範化完整路徑,並確保它包含目前作業系統的正確目錄分隔符號字元。 |
string NormalizeDirectory(params string[] path) | 取得所提供目錄的規範化完整路徑,並確保它包含目前作業系統的正確目錄分隔符號字元,且後面有斜線。 |
string EnsureTrailingSlash(string path) | 如果指定的路徑後面沒有斜線,請新增一個。 如果此路徑是空字串,請不要修改它。 |
string GetPathOfFileAbove(string file, string startingDirectory) | 搜尋並傳回目前組建檔案位置上方目錄結構中檔案的完整路徑,或根據 指定時根據 startingDirectory 。 |
GetDirectoryNameOfFileAbove(string startingDirectory, string fileName) | 找出並傳回該目錄上方目錄結構中指定目錄或位置中的檔案目錄。 |
string MakeRelative(string basePath, string path) | 讓 path 成為 basePath 的相對項。 basePath 必須是絕對目錄。 如果 path 不能成為相對的,它就會被逐字傳回。 類似於 Uri.MakeRelativeUri 。 |
string ValueOrDefault(string conditionValue, string defaultValue) | 只有當參數 'conditionValue' 為空時,才傳回參數 'defaultValue' 中的字串;否則,傳回值 conditionValue。 |
巢狀屬性函式
您可以組合屬性函式,以構成較複雜的函式,如下列範例所示。
$([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 () dotnet build
的 .NET SDK 版本中,不支援此函式。
MSBuild GetRegistryValueFromView
如果提供登錄機碼、值和一或多個已排序登錄檢視,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 () dotnet build
的 .NET SDK 版本中,不支援此函式。
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 ValueOrDefault
MSBuild ValueOrDefault
屬性函式會傳回第一個引數,除非它是 null 或空白。 如果第一個引數是 null 或空白,函式會傳回第二個引數。
下列範例顯示如何使用此函式。
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<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 |
---|---|
GetTargetFrameworkIdentifier (字串 targetFramework) | 從 TargetFramework 剖析 TargetFrameworkIdentifier。 |
GetTargetFrameworkVersion (字串 targetFramework, int versionPartCount) | 從 TargetFramework 剖析 TargetFrameworkVersion。 |
GetTargetPlatformIdentifier (字串 targetFramework) | 從 TargetFramework 剖析 TargetPlatformIdentifier。 |
GetTargetPlatformVersion (字串 targetFramework, int versionPartCount) | 從 TargetFramework 剖析 TargetPlatformVersion。 |
IsTargetFrameworkCompatible (字串 targetFrameworkTarget,字串 targetFrameworkCandidate) | 如果候選目標架構與此目標架構相容,則傳回 'True',否則傳回 false。 |
versionPartCount
和 GetTargetPlatformVersion
的參數 GetTargetFrameworkVersion
預設值為 2。
下列範例示範如何使用這些函式。
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<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>
</PropertyGroup>
<Target Name="MyTarget">
<Message Text="Value1 = $(Value1)" />
<Message Text="Value2 = $(Value2)" />
<Message Text="Value3 = $(Value3)" />
<Message Text="Value4 = $(Value4)" />
<Message Text="Value5 = $(Value5)" />
</Target>
</Project>
Value1 = .NETCoreApp
Value2 = 5.0
Value3 = windows
Value4 = 7.0
Value5 = True
MSBuild 版本比較函式
MSBuild 16.5 和更新版本會定義數個函式來比較代表版本的字串。
注意
條件中的比較運算子 可以比較可剖析為 System.Version
物件的字串,但比較可能會產生非預期的結果。 偏好屬性函式。
函式簽章 | Description |
---|---|
VersionEquals (字串 a、string b) | 如果版本 a 和 b 符合下列規則,則傳回 true 。 |
VersionGreaterThan (字串 a,字串 b) | 如果版本 a 大於 b 下列規則,則傳回 true 。 |
VersionGreaterThanOrEquals (字串 a、string b) | 如果版本 a 大於或等於 b 下列規則,則傳回 true 。 |
VersionLessThan (字串 a、string b) | 如果版本 a 小於 b 下列規則,則傳回 true 。 |
VersionLessThanOrEquals (字串 a、string b) | 如果版本 a 小於或等於 b 下列規則,則傳回 true 。 |
VersionNotEquals (字串 a、 string b) | 如果版本 a 和 b 符合下列規則,則傳回 false 。 |
在這些方法中,版本會剖析為 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 條件。