Поделиться через


Условия MSBuild

MSBuild поддерживает определенный набор условий, которые можно применять везде, где разрешен атрибут Condition; см. поддерживаемые элементы. В следующей таблице описаны эти условия.

Состояние Описание
'stringA' == 'stringB' Вычисляет true, если stringA равно stringB.

Например:

Condition="'$(Configuration)'=='DEBUG'"

Отдельные кавычки не требуются для простых буквенно-цифровых строк или логических значений. Однако для пустых значений требуются одинарные кавычки. Эта проверка не учитывает регистр.
'stringA' != 'stringB' Оценивается true, если stringA не равно stringB.

Например:

Condition="'$(Configuration)'!='DEBUG'"

Отдельные кавычки не требуются для простых буквенно-цифровых строк или логических значений. Однако для пустых значений требуются одинарные кавычки. Эта проверка не учитывает регистр.
<, >, <=, >= Вычисляет числовые значения операндов. Возвращает true, если реляционная оценка имеет значение true. Операнды должны иметь десятичное или шестнадцатеричное число или четырехкомпонентную версию. Шестнадцатеричные числа должны начинаться с 0x. Примечание. В XML символы < и > должны быть экранированы. Символ < представлен как &lt;. Символ > представлен как &gt;.
Существует('stringA') Оценивается true, если файл или папка с именем stringA существует.

Например:

Condition="!Exists('$(Folder)')"

Отдельные кавычки не требуются для простых буквенно-цифровых строк или логических значений. Однако для пустых значений требуются одинарные кавычки. Это условие не расширяет подстановочные знаки, такие как *.
HasTrailingSlash('stringA') Вычисляется как true, если указанная строка содержит символ косой черты (\) или косой черты (/).

Например:

Condition="!HasTrailingSlash('$(OutputPath)')"

Отдельные кавычки не требуются для простых буквенно-цифровых строк или логических значений. Однако для пустых значений требуются одинарные кавычки.
! Оценивается true, если операнда оценивается как false.
And Оценивается true, если оба операнда оцениваются как true.
Or Оценивается true, если по крайней мере один из операндов оценивается true.
() Механизм группировки, который оценивает true, если выражения, содержащиеся внутри, оцениваются как true.
$if$ ( %expression% ), $else$, $endif$ Проверяет, соответствует ли указанный %expression% строковое значение переданного пользовательского параметра шаблона. Если условие $if$ оценивается как true, выполняются его операторы; в противном случае проверяется условие $else$. Если условие $else$true, выполняются его операторы; в противном случае условие $endif$ завершает вычисление выражений.

Примеры использования см. в логике параметров шаблона проекта или элемента Visual Studio.

Элемент Condition является одной строкой, поэтому все строки, используемые в выражении, включая значения свойств, должны быть заключены в одинарный кавычки. Пробелы между операторами разрешены и часто используются для удобочитаемости, но они не требуются.

Чтобы использовать логические And и операторы Or, укажите операнды внутри строкового значения элемента Condition, как показано в следующем примере:

Condition="'$(Configuration)' == 'Debug' And '$(MSBuildProjectExtension)' == '.csproj'"

Логические операторы можно цепочки. Оператор And имеет более высокий приоритет, чем Or, но для ясности рекомендуется использовать скобки при использовании нескольких логических операторов, чтобы сделать порядок вычисления явным. Если вы этого не сделали, MSBuild выдает предупреждение MSB4130.

Строковые методы можно использовать в условиях, как показано в следующем примере, в котором функция TrimEnd() используется для сравнения только соответствующей части строки, чтобы различать платформы целевых платформ .NET Framework и .NET Core.

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFrameworks>net45;net48;netstandard2.1;netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
    </PropertyGroup>

    <PropertyGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
        <!-- Properties for .NET Framework -->
    </PropertyGroup>

</Project>

В файлах проекта MSBuild нет истинного логического типа. Логические данные представлены в свойствах, которые могут быть пустыми или заданы для любого значения. Таким образом, '$(Prop)' == 'true' означает "если Prop true", но '$(Prop)' != 'false' означает "если Prop true или не настроен или установлен на что-то другое".

Логическое значение логики вычисляется только в контексте условий, поэтому параметры свойств, такие как <Prop2>'$(Prop1)' == 'true'</Prop>, представлены как строка (после расширения переменной), а не вычисляются как логические значения.

MSBuild реализует несколько специальных правил обработки, чтобы упростить работу со строковыми свойствами, которые используются в качестве логических значений. Логические литералы принимаются, поэтому Condition="true" и Condition="false" работать должным образом. MSBuild также включает специальные правила для поддержки логического оператора отрицания. Таким образом, если $(Prop) имеет значение true, !$(Prop) расширяется до !true, и это значение сравнивается с false, как и ожидалось.

Сравнение версий

Реляционные операторы <, >, <=и >= поддерживают версии, проанализированные System.Version, чтобы сравнить версии с четырьмя числовыми частями друг с другом. Например, '1.2.3.4' < '1.10.0.0'true.

Осторожность

System.Version сравнения могут привести к удивительным результатам, если одна или обе версии не указывают все четыре части. Например, версия 1.1 старше версии 1.1.0.

MSBuild предоставляет функции свойств для сравнения версий с другим набором правил, совместимых с семантической версией (semver).

Расширения в условиях

В зависимости от позиции в файле проекта можно использовать расширения для свойств ($), списков элементов (@) и метаданных элементов (%). Расширения зависят от того, как MSBuild обрабатывает файлы проекта.

Свойства

Условие, содержащее выражение, например $(SomeProperty), вычисляется и преобразуется в значение свойства. Если условие находится за пределами целевого объекта, выражение вычисляется во время оценки файла проекта. Значение свойства зависит от позиции в файле проекта после расширения всех импортов. Если условие находится в целевом объекте, оно оценивается при выполнении целевого объекта, а значение влияет на любые изменения, происходящие во время выполнения сборки.

Свойство, которое не определено в точке в развернутом файле проекта, где выражение условия оценивается в пустую строку без каких-либо диагностических ошибок или предупреждений.

Списки элементов

Условие, содержащее выражение @-expression, например @(SomeItems), расширяется в группах элементов на верхнем уровне и в целевых объектах.

Элементы могут зависеть от любого свойства и могут зависеть от элементов, которые уже определены в последовательности.

Причина заключается в том, что MSBuild обрабатывает файлы проекта несколькими проходами. После начальной оценки свойства и прохождения расширения импорта выполняется проверка элемента. Таким образом, @-expressions разрешены в любом условии, которое вычисляется после того, как элементы начали определяться. То есть в элементах, группах элементов и в целевых объектах.

Метаданные

Условие, содержащее выражение метаданных, например %(ItemMetadata), расширяется в том же контексте, что и списки элементов, то есть в группах элементов на верхнем уровне и в целевых объектах. Однако расширение может иметь другое поведение в группе элементов в зависимости от того, находится ли группа элементов вне целевого объекта или внутри целевого объекта. Кроме того, из различных форм выражений метаданных, %(ItemName.MetadataName), %(JustTheMetadataName)и @(ItemName->'%(MetadataName)'), допускается только преобразование элемента (последний) за пределами целевого объекта. Значение %-expression в целевом объекте вычисляется во время выполнения и зависит от любых изменений состояния во время выполнения целевого объекта. Выполнение целевого объекта и значения любого %-expressions, содержащихся в нем, также зависит от пакетирования целевого объекта, а также может активировать пакетирование; см. пакетнойMSBuild.

Поддерживаемые элементы

Следующие элементы поддерживают атрибут Condition:

  • Импорт
  • ImportGroup
  • Пункт
  • ItemDefinitionGroup
  • ItemGroup
  • ItemMetadata
  • OnError
  • Выпуск
  • Свойство
  • PropertyGroup
  • Цель
  • Задача
  • UsingTask
  • Когда

См. также