屬性函式

屬性函式是 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>

在靜態屬性函式中,您可以使用以下系統類別的靜態方法或屬性:

此外,您可以使用下列靜態方法和屬性:

在靜態屬性上呼叫執行個體方法

如果您存取的靜態屬性傳回物件執行個體,您就可以叫用該物件的執行個體方法。 若要叫用實例方法,請使用下列語法,其中 < 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) 指定目前的作業系統平台是否為 platformStringplatformString 必須是 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))))

這個範例會傳回 的值 FileAttributesArchive 位 (路徑 tempFile 所指定檔案的 32 或 0) 。 請注意,列舉的資料值無法在某些內容中依名稱顯示。 在上一個範例中,必須改用數值 (32) 。 在其他情況下,根據所呼叫方法的預期而定,必須使用列舉資料值。 在下列範例中,列舉值 RegexOptionsECMAScript 必須使用 ,因為無法轉換數值,因為此方法預期。

<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。

versionPartCountGetTargetPlatformVersion 的參數 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) 如果版本 ab 符合下列規則,則傳回 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) 如果版本 ab 符合下列規則,則傳回 false

在這些方法中,版本會剖析為 System.Version ,但有下列例外狀況:

  • 前置 vV 會被忽略,這允許與 比較 $(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 條件函式

函式 ExistsHasTrailingSlash 不是屬性函式。 它們可與 屬性搭配 Condition 使用。 請參閱 MSBuild 條件

另請參閱