Функции свойств

Функции свойств — это вызовы методов .NET, которые отображаются в определениях свойств MSBuild. В отличие от задач, функции свойств можно использовать за пределами целевых объектов. Функции свойств оцениваются всякий раз при развертывании свойств или элементов. Таким образом, для свойств и элементов вне каких-либо целевых объектов функции свойств оцениваются перед любым целевым запуском. Для групп свойств и групп элементов внутри целевых объектов функции свойств оцениваются при оценке целевого объекта.

Без использования задач MSBuild вы можете читать системное время, сравнивать строки, сопоставлять регулярные выражения и выполнять другие действия в скрипте построения. MSBuild попытается преобразовать строку в число и число в строку и при необходимости выполнит другие преобразования.

В строковых значениях, возвращаемых из функций свойства, специальные символы преобразованы в escape-символы. Если нужно, чтобы значение обрабатывалось как значение непосредственно в файле проекта, воспользуйтесь функцией $([MSBuild]::Unescape()), чтобы преобразовать специальные символы в обычный формат.

Синтаксис функции свойства

Существуют три типа функций свойства, каждая из которых имеет свой синтаксис.

  • Функции свойства строки (экземпляра)
  • Функции статичного свойства
  • Функции свойства 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.OperatingSystem

Функции System.OperatingSystem свойств возвращают сведения об операционной системе, в которой выполняется MSBuild. Например, если проект предназначен для Linux и вы создаете его на macOS, функции свойств возвращают сведения о macOS.

В MSBuild, работающем в .NET (dotnet build), все статические методы System.OperatingSystem класса будут вызываться как статические функции свойств.

В MSBuild, работающем на платформа .NET Framework (MSBuild.exe), только следующие методы System.OperatingSystem будут вызываться как статические функции свойств. MSBuild реализует их внутренне, так как System.OperatingSystem не определяет их на платформа .NET Framework. Методы для операционных систем, для которых нет пакета SDK для .NET, например System.OperatingSystem::IsTvOS, не вызываются.

В следующем примере показано использование этих функций свойств.

<IsWindows>$([System.OperatingSystem]::IsWindows())</IsWindows>

Вызов методов экземпляра для статических свойств

При доступе к статическому свойству, которое возвращает экземпляр объектов, можно вызывать методы экземпляра этого объекта. Чтобы вызвать метод экземпляра, используйте следующий синтаксис, где Class имя системного класса, Property является именем свойства, Method является именем метода и (Parameters) является списком параметров для метода:

$([Class]::Property.Method(Parameters))

Имя класса должно содержать полное пространство имен.

Например, чтобы задать свойство построения на текущую дату, можно использовать следующий код.

<Today>$([System.DateTime]::Now.ToString('yyyy.MM.dd'))</Today>

Функции свойства MSBuild

Для обеспечения арифметической побитовой логической поддержки escape-символов можно использовать несколько статических методов из вашего построения. Доступ к этим методам осуществляется с помощью следующего синтаксиса, где Method имя метода и (Parameters) является списком параметров для метода.

$([MSBuild]::Method(Parameters))

Например, чтобы добавить два свойства с числовыми значениями, используйте следующий код.

$([MSBuild]::Add($(NumberOne), $(NumberTwo)))

Приведем список функций свойства MSBuild.

Сигнатура функции Description
double Add(double a, double b) Сложение двух значений double.
long Add(long a, long b) Сложение двух значений long.
double Subtract(double a, double b) Вычитание двух значений double.
long Subtract(long a, long b) Вычитание двух значений long.
double Multiply(double a, double b) Умножение двух значений double.
long Multiply(long a, long b) Умножение двух значений long.
double Divide(double a, double b) Деление двух значений double.
long Divide(long a, long b) Деление двух значений long.
double Modulo(double a, double b) Остаток от деления двух значений double.
long Modulo(long a, long b) Остаток от деления двух значений long.
string Escape(string unescaped) Escape-последовательность строки в соответствии с правилами экранирования MSBuild.
string Unescape(string escaped) Unescape-последовательность строки в соответствии с правилами экранирования MSBuild.
int BitwiseOr(int first, int second) Примените побитовый параметр OR к первому и второму значению (first | second).
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() Значение true, если текущая операционная система — это система Unix.
string NormalizePath(params string[] path) Возвращает канонический полный путь для предоставленного пути и проверяет правильность знаков разделения для каталогов, используемых в текущей операционной системе.
string NormalizeDirectory(params string[] path) Возвращает канонический полный путь для предоставленного каталога и проверяет правильность знаков разделения для каталогов, используемых в текущей операционной системе, а также наличие косой черты в конце.
string EnsureTrailingSlash(string path) Если в конце заданного пути нет косой черты, она добавляется. Если путь является пустой строкой, он не изменяется.
string GetPathOfFileAbove(string file, string startingDirectory) Выполняет поиск и возвращает полный путь к файлу в структуре каталогов в расположении текущего файла сборки или в зависимости от startingDirectoryуказанного значения.
string GetDirectoryNameOfFileAbove(string startingDirectory, string fileName) Поиск и возврат каталога файла в указанном каталоге либо расположении в структуре каталогов над ним.
string MakeRelative(string basePath, string path) Делает path относительным для basePath. basePath должен быть абсолютным каталогом. Если path невозможно сделать относительным, он возвращается дословно. Аналогично Uri.MakeRelativeUri.
string ValueOrDefault(string conditionValue, string defaultValue) Возвращает строку в параметре, только если параметр defaultValueconditionValue пуст, в противном случае возвращает значение conditionValue.
string ConvertToBase64(string toEncode) Возвращает строку после преобразования всех байтов в базовые 64 (буквенно-цифровые символы плюс + и /), заканчивающуюся одним или двумя =.
string ConvertFromBase64(string toDecode) Возвращает строку после преобразования из базового 64 (буквенно-цифровые символы плюс + и /), заканчивающуюся одним или двумя =.

Вложенные функции свойства

Вы можете объединить функции свойств для формирования более сложных функций, как показано в следующем примере:

$([MSBuild]::BitwiseAnd(32, $([System.IO.File]::GetAttributes(tempFile))))

В этом примере возвращается значение FileAttributes.Archive (32 или 0) файла, заданного путем tempFile. Обратите внимание, что перечисляемые значения данных в некоторых контекстах не могут отображаться по имени. В предыдущем примере вместо этого следует использовать числовое значение (32). В других случаях (в зависимости от ожиданий вызываемого метода) нужно использовать значение данных перечисления. В следующем примере значение RegexOptionsперечисления.ECMAScript, так как числовое значение нельзя преобразовать в соответствии с ожиданиями этого метода.

<PropertyGroup>
    <GitVersionHeightWithOffset>$([System.Text.RegularExpressions.Regex]::Replace("$(PrereleaseVersion)", "^.*?(\d+)$", "$1", "System.Text.RegularExpressions.RegexOptions.ECMAScript"))</GitVersionHeightWithOffset>
</PropertyGroup>

Во вложенных функциях свойства могут также появляться метаданные. Дополнительные сведения см. в статье Пакетная обработка.

MSBuild DoesTaskHostExist

Функция свойства DoesTaskHostExist в MSBuild возвращает сведения об установленном сервере задач для указанной среды выполнения и значение архитектуры.

Эта функция свойства использует следующий синтаксис.

$([MSBuild]::DoesTaskHostExist(string theRuntime, string theArchitecture))

MSBuild EnsureTrailingSlash

Функция свойства EnsureTrailingSlash в MSBuild добавляет косую черту, если таковая отсутствует.

Эта функция свойства использует следующий синтаксис.

$([MSBuild]::EnsureTrailingSlash('$(PathProperty)'))

MSBuild GetDirectoryNameOfFileAbove

Функция свойства GetDirectoryNameOfFileAbove MSBuild выполняет поиск каталога, содержащего указанный файл, начиная с указанного каталога включительно. Она возвращает полный путь к ближайшему каталогу, содержащему файл, если он найден. В противном случае — пустую строку.

Эта функция свойства использует следующий синтаксис.

$([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

Функция свойства GetPathOfFileAbove MSBuild выполняет поиск каталога, содержащего указанный файл, начиная с указанного каталога включительно. Она возвращает полный путь к ближайшему совпадающему файлу, если он найден. В противном случае — пустую строку.

Эта функция свойства использует следующий синтаксис.

$([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

Функция свойства GetRegistryValue в MSBuild возвращает значение раздела реестра. Она принимает два аргумента — имя раздела и имя значения — и возвращает значение в реестр. Если не указано имя значения, возвращается значение по умолчанию.

В следующих примерах показано, как используется эта функция.

$([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

Предупреждение

В версии пакета SDK MSBuild (dotnet build) для .NET, эта функция не поддерживаются.

MSBuild GetRegistryValueFromView

Функция свойства GetRegistryValueFromView в MSBuild получает данные системного реестра с учетом раздела реестра, значения и одного или нескольких упорядоченных представлений реестра. Раздел и значения ищутся в каждом представлении реестра по порядку, пока не будут найдены.

Синтаксис функции свойства.

[MSBuild]::GetRegistryValueFromView(string keyName, string valueName, object defaultValue, params object[] views)

64-разрядная операционная система Windows ведет раздел реестра HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node, содержащий представление реестра HKEY_LOCAL_MACHINE\SOFTWARE для 32-разрядных приложений.

По умолчанию 32-разрядное приложение, работающее на WOW64, получает доступ к 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))

В этом примере данные SLRuntimeInstallPath получаются из раздела ReferenceAssemblies, но сначала поиск выполняется в 64-разрядном представлении реестра, а затем — в 32-разрядном.

Предупреждение

В версии пакета SDK MSBuild (dotnet build) для .NET, эта функция не поддерживаются.

MSBuild MakeRelative

Функция свойства MakeRelative в MSBuild возвращает путь второго пути относительно первого пути. Каждый путь может быть файлом или папкой.

Эта функция свойства использует следующий синтаксис.

$([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 используется, и является стабильным в архитектуре платформы, в отличие от метода GetHashCode.NET. Она не гарантируется стабильной в разных версиях 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.0 эта функция принимает второй, необязательный аргумент, запрашивающий алгоритм хэширования для использования:

<Project>
   <PropertyGroup>
      <MyHash>$([MSBuild]::StableStringHash("test1", "Sha256"))</MyHash>
   </PropertyGroup>

   <Target Name="WriteHash" AfterTargets="Build">
      <Message Text="Hash: $(MyHash)"/>
   </Target>
</Project>

Второй аргумент является нечувствительным к регистру и в настоящее время поддерживает следующие значения:

  • Устаревшая версия — сохраняет то же поведение, что и вызов функции без второго аргумента. Возвращает целое число со знаком 32 бит с аналогичными свойствами, как string.GetHashCode.
  • Fnv1a32bit — возвращает подписанное 32-разрядное целое число, представляющее хэш Fowler-Noll-Vo версии 1a для заданной строки.
  • Fnv1a64bit — возвращает подписанное 64-разрядное целое число, представляющее хэш Fowler-Noll-Vo версии 1a для заданной строки.
  • Sha256 — возвращает нерекоменданную шестнадцатеричную строку, представляющую хэш SHA256 заданной строки.

MSBuild ValueOrDefault

Функция свойства ValueOrDefault в MSBuild возвращает первый аргумент, если он не нулевой или пустой. Если первый аргумент нулевой, функция возвращает второй аргумент.

В следующем примере показано, как используется эта функция.

<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(string targetFramework) Анализирует TargetFrameworkIdentifier из TargetFramework.
GetTargetFrameworkVersion(string targetFramework, int versionPartCount) Анализирует TargetFrameworkVersion из TargetFramework.
GetTargetPlatformIdentifier(string targetFramework) Анализирует TargetPlatformIdentifier из TargetFramework.
GetTargetPlatformVersion(string targetFramework, int versionPartCount) Анализирует TargetPlatformVersion из TargetFramework.
IsTargetFrameworkCompatible(string targetFrameworkTarget, string targetFrameworkCandidate) Возвращает значение True, если целевая платформа кандидата (второй аргумент) совместима с целевой платформой, указанной первым аргументом, и значение false в противном случае.

По умолчанию для параметра versionPartCountGetTargetFrameworkVersion и GetTargetPlatformVersion установлено значение 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>
        <Value6>$([MSBuild]::IsTargetFrameworkCompatible('net5.0', 'net6.0'))</Value6>
        <Value7>$([MSBuild]::IsTargetFrameworkCompatible('net5.0', 'net8.0'))</Value7>
    </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)" />
    </Target>
</Project>
Value1 = .NETCoreApp
Value2 = 5.0
Value3 = windows
Value4 = 7.0
Value5 = True
Value6 = False
Value7 = False

Функции сравнения версий 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.