Настройка целевых платформ и задач

Некоторые задачи MSBuild можно настроить на выполнение в целевой среде, если компьютер разработчика ее поддерживает. Например, если вы выполняете на компьютере с 64-разрядной версией Windows сборку приложения, предназначенного для 32-разрядной архитектуры Windows, эти задачи будут выполняться в 32-разрядном процессе.

Примечание.

Если задача сборки написана на языке .NET, например Visual C# или Visual Basic, и не использует собственные ресурсы и средства, она будет без адаптации выполняться в любом целевом контексте.

Параметры задачи и атрибуты UsingTask

Следующие атрибуты UsingTask влияют на все операции, выполняемые задачей в конкретном процессе сборки:

  • Атрибут Runtime, если указан, задает версию среды выполнения (CLR). Он может принимать любое из следующих значений: CLR2, CLR4, CurrentRuntime или * (любая среда выполнения).

  • Атрибут Architecture, если указан, задает платформу и разрядность. Он может принимать любое из следующих значений: x86, x64, CurrentArchitecture или * (любая архитектура).

  • Атрибут TaskFactory, если указан, задает фабрику задач, которая создает и выполняет экземпляр задачи. Он принимает только одно значение: TaskHostFactory. Дополнительные сведения см. далее в этой статье в разделе Фабрики задач.

<UsingTask TaskName="SimpleTask"
    Runtime="CLR2"
    Architecture="x86"
    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v3.5.dll" />

Также с помощью параметров MSBuildRuntime и MSBuildArchitecture можно задать целевой контекст для вызова отдельной задачи.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="MyTarget">
        <SimpleTask MSBuildRuntime="CLR2" MSBuildArchitecture= "x86"/>
    </Target>
</Project>

Перед выполнением задачи MSBuild выполняет поиск соответствующего элемента UsingTask с таким же целевым контекстом. Если параметр задан в элементе UsingTask, но не задан в соответствующей задаче, он считается совпадающим. Если параметр задан в задаче, но не задан в соответствующем элементе UsingTask, он также считается совпадающим. Если для параметра не указаны значения ни в UsingTask, ни в задаче, для него по умолчанию используется значение * (любой параметр).

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

Если существует более одного элемента UsingTask и для каждого из них есть соответствующие атрибуты TaskName, Runtime и Architecture, первый прошедший оценку заменяет остальные. В этом состоит отличие от поведения элементов Property и Target.

Если параметры заданы в задаче, MSBuild пытается найти UsingTask, который соответствует этим параметрам или по крайней мере не конфликтует с ними. Несколько UsingTask могут определять целевой контекст для одной задачи. Например, задача с несколькими исполняемыми файлами для разных целевых сред может выглядеть примерно так:

<UsingTask TaskName="MyTool"
    Runtime="CLR2"
    Architecture="x86"
    AssemblyFile="$(MyToolsPath)\MyTool.v2.0.dll" />

<UsingTask TaskName="MyTool"
    Runtime="CLR4"
    Architecture="x86"
    AssemblyFile="$(MyToolsPath)\MyTool.4.0.dll" />

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="MyTarget">
        <MyTool MSBuildRuntime="CLR2" MSBuildArchitecture= "x86"/>
    </Target>
</Project>

Переопределение UsingTask по умолчанию

По умолчанию MSBuild обрабатывает UsingTask по принципу "приоритет первого". Начиная с версии 17.2 MSBuild поддерживает переопределение этого поведения с помощью параметра Override. UsingTask с параметром Override, принимающим значение true, будет иметь больший приоритет, чем любой другой элемент UsingTask с тем же TaskName.

<UsingTask TaskName="MyTool"
    Runtime="CLR4"
    Architecture="x86"
    Override="true"
    AssemblyFile="$(MyToolsPath)\MyTool.4.0.dll" />

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

Это действие можно выполнить только один раз для каждой задачи. Выполнение сборок с несколькими переопределениями для одной задачи завершится ошибкой MSBuild MSB4275.

Фабрики задач

Перед выполнением задачи MSBuild проверяет, предназначена ли она для выполнения в текущем контексте программного обеспечения. Если задача назначена таким образом, MSBuild передает ее AssemblyTaskFactoryв объект , который запускает его в текущем процессе; в противном случае MSBuild передает задачу в задачу, которая запускает задачу TaskHostFactoryв процессе, который соответствует целевому контексту. Даже если текущий контекст соответствует целевому, вы можете принудительно выполнить задачу в отдельном процессе (для изоляции, из соображений безопасности или по другим причинам), указав для параметра TaskFactory значение TaskHostFactory.

<UsingTask TaskName="MisbehavingTask"
    TaskFactory="TaskHostFactory"
    AssemblyFile="$(MSBuildToolsPath)\MyTasks.dll">
</UsingTask>

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

Фантомные параметры задачи

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

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <FrameworkVersion>3.0</FrameworkVersion>
    </PropertyGroup>
    <Target Name="MyTarget">
        <SimpleTask MSBuildRuntime="$(FrameworkVerion)" MSBuildArchitecture= "x86"/>
    </Target>
</Project>

В отличие от других параметров задач, MSBuildRuntime и MSBuildArchitecture не очевидны для самой задачи. Чтобы написать задачу, учитывающую контекст, в котором она выполняется, нужно проверить контекст, вызвав платформу .NET Framework, либо использовать свойства сборки для передачи сведений о контексте через другие параметры задачи.

Примечание.

Атрибуты UsingTask можно задать из набора инструментов и свойств среды.

Параметры MSBuildRuntime и MSBuildArchitecture предоставляют самый гибкий способ задать целевой контекст, но при этом имеют наиболее ограниченную область действия. С одной стороны, так как они задаются для самого экземпляра задачи и не вычисляются до выполнения задачи, они могут наследовать свои значения от полного набора свойств, доступных во время вычисления и построения. С другой стороны, эти параметры применяются только к определенному экземпляру задачи в конкретном целевом объекте.

Примечание.

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