Настройка целевых объектов и задач

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

Замечание

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

Использование атрибутов и параметров задачи UsingTask

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

  • АтрибутRuntime, если он присутствует, задает версию среды CLR и может принимать любое из этих значений: CLR2, CLR4, CurrentRuntimeNET (начиная с пакета SDK для .NET 10/Visual Studio 2026/MSBuild 18.0) или * (любая среда выполнения).

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

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

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

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

<Project>
    <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>
    <Target Name="MyTarget">
        <MyTool MSBuildRuntime="CLR2" MSBuildArchitecture= "x86"/>
    </Target>
</Project>

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

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

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

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

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

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

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

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

<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 , которая ограничена версией MSBuild .NET Framework. См. встроенные задачи MSBuild. Эта фабрика задач поддерживается, но более новый код должен использоваться RoslynCodeTaskFactory для более широкого применения.

TaskHosts в MSBuild

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

На протяжении истории TaskHosts позволяли задачам выполняться в отдельных процессах .NET Framework определенных версий (например, CLR2 или CLR4). Эта поддержка регулируется атрибутами RuntimeArchitecture<UsingTask> элемента в файле проекта или целевом файле:

  • Architectureможет указывать такие значения, как x86, x64CurrentArchitectureили * для любой архитектуры.
  • Runtime может указывать такие значения, как CLR2, CLR4и (недавно) NET или CurrentRuntime.

Для большинства задач MSBuild процесс по умолчанию достаточен. Но для пользовательских или более сложных задач, особенно с зависимостями, зависящими от платформы, TaskHosts разблокирует совместимость и гибкость, запуская подходящую среду выполнения автоматически.

Использование .NET TaskHost

С выпуском пакета SDK для .NET 10 и Visual Studio 2026 в MSBuild появилась поддержка для .NET TaskHost. Эта функция позволяет MSBuild выполнять задачи, которые должны использовать среду выполнения .NET в отдельном процессе .NET. Это включено с помощью атрибута Runtime="NET" в элементе <UsingTask> :

<UsingTask TaskName="MyNetTask"
           Runtime="NET"
           AssemblyFile="path\to\task.dll" />

Если этот атрибут задан, выполните указанные ниже действия.

  • MSBuild автоматически управляет пулом процессов .NET TaskHost и выполняет указанную задачу на узле в этом пуле.
  • Задачи могут воспользоваться преимуществами API или библиотек, эксклюзивных для современных сред выполнения .NET.
  • Изоляция защищает процесс сборки от конфликтов зависимостей или версий.

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

Эта .NET TaskHost возможность с использованием Runtime="NET" поддерживается начиная с MSBuild 18.0 (SDK .NET 10 / Visual Studio 2026) и в настоящее время поддерживается только для проектов использующих Microsoft.NET.Sdk.

Если вы отправляете целевые объекты, которые должны работать со старыми наборами инструментов MSBuild, можно условно выбрать UsingTask определение на основе текущей версии MSBuild (и, если применимо, $(MSBuildRuntimeType)):

<UsingTask TaskName="MyTask"
           Runtime="NET"
           AssemblyFile="my/net/tasks.dll"
           Condition="$([MSBuild]::VersionGreaterThanOrEquals('$(MSBuildVersion)', '18.0'))" />

<UsingTask TaskName="MyTask"
           Runtime="CLR4"
           AssemblyFile="my/netframework/tasks.dll"
           Condition="!$([MSBuild]::VersionGreaterThanOrEquals('$(MSBuildVersion)', '18.0')) and '$(MSBuildRuntimeType)' == 'Full'" />

Почему используйте .NET TaskHost?

  • Доступ к современным API .NET: .NET TaskHost позволяет задачам использовать функции и библиотеки, доступные только в последних выпусках .NET.
  • Улучшена совместимость: Разделение выполнения задачи может избежать конфликтов версий и зависимостей.
  • Обеспечение на будущее: Мы намерены расширить поддержку TaskHost и объединить логику SDK/резолвера (см. dotnet/msbuild#12895 для информации о текущей работе).

Параметры фантомной задачи

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

<Project>
    <PropertyGroup>
        <FrameworkVersion>3.0</FrameworkVersion>
    </PropertyGroup>
    <Target Name="MyTarget">
        <SimpleTask MSBuildRuntime="$(FrameworkVersion)" MSBuildArchitecture= "x86"/>
    </Target>
</Project>

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

Замечание

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

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

Замечание

Параметры задачи оцениваются в контексте родительского узла, а не в контексте узла задачи. Переменные среды, зависящие от среды выполнения или архитектуры (например, расположение program Files ), оцениваются как значение, соответствующее родительскому узлу. Однако если та же переменная среды считывается непосредственно задачей, она правильно оценивается в контексте узла задач.