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


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

Некоторые задачи 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:

Фабрика задач Description
AssemblyTaskFactory Это значение по умолчанию. Выполняет задачу в процессе.
TaskHostFactory Выполняет задачу вне процесса.
RoslynCodeTaskFactory Для встроенных задач, написанных на C# или Visual Basic и предназначенных для .NET Standard; работает с обоими msbuild.exe и dotnet build.
CodeTaskFactory Для встроенных задач, написанных на C# или Visual Basic и предназначенных платформа .NET Framework; работает только с msbuild.exe.

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

TaskHostFactory

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

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

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

RoslynCodeTaskFactory

Предоставляет RoslynCodeTaskFactory механизм, с помощью которого можно написать код C# или Visual Basic для задачи в файле проекта для немедленного использования. Код компилируется во время процесса сборки, чтобы создать задачу, которую можно выполнить в той же сборке. Код, который вы пишете, предназначен для .NET Standard, поэтому его можно использовать при выполненииdotnet build, который использует версию .NET Core (и .NET 5 и более поздних версий) MSBuild, а также msbuild.exeиспользует платформа .NET Framework. RoslynCodeTaskFactory лучше всего подходит для настройки, которая слишком трудно сделать в логике MSBuild, но недостаточно сложная, чтобы создать отдельный проект. См. статью "Создание встроенной задачи MSBuild" с помощью RoslynCodeTaskFactory.

CodeTaskFactory

CodeTaskFactoryявляется более старой версиейRoslynCodeTaskFactory, которая ограничена платформа .NET Framework версией MSBuild. См . встроенные задачи MSBuild. Эта фабрика задач поддерживается, но более новый код должен использоваться RoslynCodeTaskFactory для более широкого применения.

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

Как и любые другие параметры задачи, 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), будут вычисляться в значение, соответствующее родительскому узлу. Но если та же самая переменная среды считывается непосредственно задачей, она корректно вычисляется в контексте узла задачи.