свойства MSBuild

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

Определение свойств и указание ссылок на них в файле проекта

Для объявления свойства создается элемент с таким же именем как у свойства, который является дочерним по отношению к элементу PropertyGroup. Например, в следующем XML-коде создается свойство BuildDir со значением Build.

<PropertyGroup>
    <BuildDir>Build</BuildDir>
</PropertyGroup>

Допустимые имена свойств начинаются с прописной или строчной буквы или подчеркивания (_); допустимые последующие символы включают буквенно-цифровые символы (буквы или цифры), подчеркивание и дефис (-).

Для обращения к свойствам в файле проекта используется синтаксис $(<PropertyName>). В предыдущем примере обращение к свойству осуществляется с помощью оператора $(BuildDir).

Значения свойств можно изменить путем переопределения свойств. Для свойства BuildDir можно задать новое значение, используя следующий XML-код:

<PropertyGroup>
    <BuildDir>Alternate</BuildDir>
</PropertyGroup>

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

Зарезервированные свойства

MSBuild резервирует некоторые имена свойств для хранения сведений о файле проекта и двоичных файлах MSBuild. Обращение к этим свойствам, так же как и к другим свойствам, осуществляется с помощью символа $. Например, оператор $(MSBuildProjectFile) возвращает полное имя файла проекта, включая расширение.

Дополнительные сведения см. в статьях Практическое руководство. Использование ссылки на имя или расположение файла проекта и Зарезервированные и стандартные свойства MSBuild.

Внутренние свойства MSBuild

Свойства, определенные в стандартных файлах импорта, которые начинаются с подчеркивания (_) являются частными для MSBuild и не должны быть считываются, сбрасываются или переопределяются в пользовательском коде.

Свойства среды

Обращаться к переменным среды в файлах проектов можно так же как к зарезервированным свойствам. Например, чтобы использовать переменную среды PATH в файле проекта, укажите оператор $(Path). Если проект содержит определение свойства с тем же именем, что и у свойства среды, свойство в проекте переопределит значение переменной среды.

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

Чтобы получить текущее значение переменные среды из порожденного средства, можно использовать функции свойства System.Environment.GetEnvironmentVariable. Однако рекомендуется использовать параметр задачи EnvironmentVariables. Свойства среды, заданные в этом массиве строк, могут быть переданы в порожденное средство без изменения переменных среды.

Совет

Не все переменные среды считываются в качестве исходных свойств. Все переменные среды, имена которых не являются допустимыми именами свойств MSBuild, например "386", игнорируются.

Дополнительные сведения см. в статье Практическое руководство. Использование переменных среды в сборке.

Свойство реестра

Значения разделов системного реестра можно считывать, используя следующий синтаксис. Здесь Hive — это куст реестра (например, HKEY_LOCAL_MACHINE), MyKey — имя раздела, MySubKey — имя подраздела, Value — значение подраздела.

$(registry:Hive\MyKey\MySubKey@Value)

Чтобы получить значение подраздела по умолчанию, опустите Value.

$(registry:Hive\MyKey\MySubKey)

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

<PropertyGroup>
  <VisualStudioWebBrowserHomePage>
    $(registry:HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\14.0\WebBrowser@HomePage)
  </VisualStudioWebBrowserHomePage>
<PropertyGroup>

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

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

Создание свойств во время выполнения

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

  • Свойство может создано любой задачей. Для создания свойства элемент Задача должен иметь дочерний элемент Выходные данные с атрибутом PropertyName.

  • Свойство может создано задачей CreateProperty. Этот способ не рекомендуется использовать.

  • Элементы Target могут содержать элементы PropertyGroup, которые могут включать объявления свойств.

Глобальные свойства

MSBuild позволяет задавать свойства в командной строке с помощью параметра -property (или -p). Эти значения глобальных свойств переопределяют значения свойств, заданные в файле проекта. Это относится также к свойствам среды за исключением зарезервированных свойств, которые нельзя изменить.

В следующем примере показано, как присвоить глобальному свойству Configuration значение DEBUG.

msbuild.exe MyProj.proj -p:Configuration=DEBUG

Кроме того, глобальные свойства можно задавать или изменять для дочерних проектов в сборках из нескольких проектов, используя атрибут Properties задачи MSBuild. Глобальные свойства также передаются в дочерние проекты, если только с помощью атрибута RemoveProperties задачи MSBuild не указан список свойств, которые не должны передаваться. Дополнительные сведения см. в разделе Задача MSBuild.

Локальные свойства

Локальные свойства можно сбросить в проекте. Глобальные свойства не могут. Если локальное свойство задано из командной строки с -p параметром, параметр в файле проекта имеет приоритет над командной строкой.

Вы указываете локальное свойство с помощью атрибута TreatAsLocalProperty в теге проекта.

Следующий код указывает, что два свойства являются локальными:

<Project Sdk="Microsoft.Net.Sdk" TreatAsLocalProperty="Prop1;Prop2">

Локальные свойства не перенаправляются дочерним проектам в сборке с несколькими проектами. Если вы предоставляете значение в командной строке с -p параметром, дочерние проекты получают значение глобального свойства вместо локального значения, измененного в родительском проекте, но дочерний проект (или любой из его импортов) также может изменить его собственным TreatAsLocalProperty.

Пример с локальными свойствами

В следующем примере кода показан эффект TreatAsLocalProperty:

<!-- test1.proj -->
<Project TreatAsLocalProperty="TreatedAsLocalProp">
    <PropertyGroup>
        <TreatedAsLocalProp>LocalOverrideValue</TreatedAsLocalProp>
    </PropertyGroup>

    <Target Name="Go">
        <MSBuild Projects="$(MSBuildThisFileDirectory)\test2.proj" Targets="Go2" Properties="Inner=true" />
    </Target>

    <Target Name="Go2" BeforeTargets="Go">
        <Warning Text="TreatedAsLocalProp($(MSBuildThisFileName)): $(TreatedAsLocalProp)" />
    </Target>
</Project>
<!-- test2.proj -->
<Project TreatAsLocalProperty="TreatedAsLocalProp">
    <Target Name="Go2">
        <Warning Text="TreatedAsLocalProp($(MSBuildThisFileName)): $(TreatedAsLocalProp)" />
    </Target>
</Project>

Предположим, вы создадите командную строку test1.proj и присвойте TreatedAsLocalProperty глобальному значению GlobalOverrideValue:

dotnet msbuild .\test1.proj -p:TreatedAsLocalProp=GlobalOverrideValue

Вывод выглядит следующим образом.

test1.proj(11,9): warning : TreatedAsLocalProp(test): LocalOverrideValue
test2.proj(3,9): warning : TreatedAsLocalProp(test2): GlobalOverrideValue

Дочерний проект наследует глобальное значение, но родительский проект использует локально заданное свойство.

Локальные свойства и импорт

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

В следующем примере кода показан эффект TreatAsLocalProperty импортированного проекта:

<!-- importer.proj -->
<Project>
    <PropertyGroup>
        <TreatedAsLocalProp>FirstOverrideValue</TreatedAsLocalProp>
    </PropertyGroup>

    <Import Project="import.props" />

    <PropertyGroup>
        <TreatedAsLocalProp Condition=" '$(TrySecondOverride)' == 'true' ">SecondOverrideValue</TreatedAsLocalProp>
    </PropertyGroup>

    <Target Name="Go">
        <Warning Text="TreatedAsLocalProp($(MSBuildThisFileName)): $(TreatedAsLocalProp)" />
    </Target>
</Project>
<!-- import.proj -->
<Project TreatAsLocalProperty="TreatedAsLocalProp">
    <PropertyGroup>
        <TreatedAsLocalProp>ImportOverrideValue</TreatedAsLocalProp>
    </PropertyGroup>

    <!-- Here, TreatedAsLocalProp has the value "ImportOverrideValue"-->
</Project>

Предположим, что вы создаете importer.proj и задаете глобальное значение TreatedAsLocalProp следующим образом:

dotnet msbuild .\importer.proj -p:TreatedAsLocalProp=GlobalOverrideValue

Результат выглядит так:

importer.proj(9,9): warning : TreatedAsLocalProp(importer.proj): GlobalOverrideValue

Теперь предположим, что вы выполняете сборку со свойством TrySecondOverride true:

dotnet msbuild .\importer.proj -p:TreatedAsLocalProp=GlobalOverrideValue -p:TrySecondOverride=true

Результат выглядит так:

importer.proj(13,9): warning : TreatedAsLocalProp(importer.proj): SecondOverrideValue

В примере показано, что свойство обрабатывается как локальное после импортированного проекта, где TreatAsLocalProperty использовался атрибут, а не только в импортированном файле. Значение свойства влияет на глобальное переопределение, но только перед импортированным проектом, где TreatAsLocalProperty используется.

Дополнительные сведения см. в разделах Элемент Project (MSBuild) и Практическое руководство. Сборка одинаковых исходных файлов с различными параметрами.

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

Начиная с .NET Framework версии 4, для оценки сценариев MSBuild можно использовать функции свойств. Получить системное время, сравнить строки, проверить регулярные выражения и выполнить другие действия можно в сценарии сборки без использования задач MSBuild.

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

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

Дополнительные сведения и список функций свойств см. в разделе Функции свойства.

Сохранение XML-кода в свойствах

Свойства могут содержать произвольный XML-код, предназначенный для передачи значений задачам или отображения сведений из журналов. В следующем примере показано свойство ConfigTemplate, которое имеет значение, содержащее XML-код и ссылки на другие свойства. MSBuild заменяет ссылки на свойства соответствующими значениями свойств. Значения свойств присваиваются в том порядке, в каком они появляются. Таким образом, в этом примере $(MySupportedVersion), $(MyRequiredVersion) и $(MySafeMode) должны быть уже определены.

<PropertyGroup>
    <ConfigTemplate>
        <Configuration>
            <Startup>
                <SupportedRuntime
                    ImageVersion="$(MySupportedVersion)"
                    Version="$(MySupportedVersion)"/>
                <RequiredRuntime
                    ImageVersion="$(MyRequiredVersion)"
                    Version="$(MyRequiredVersion)"
                    SafeMode="$(MySafeMode)"/>
            </Startup>
        </Configuration>
    </ConfigTemplate>
</PropertyGroup>