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


Встроенные задачи MSBuild

Задачи MSBuild, как правило, создаются путем компиляции класса, реализующего интерфейс ITask.Дополнительные сведения см. в разделе Задачи MSBuild.

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

Структура встроенной задачи

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

<Project ToolsVersion="4.0" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
  <!-- This simple inline task does nothing. -->
  <UsingTask
    TaskName="DoNothing"
    TaskFactory="CodeTaskFactory"
    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
    <ParameterGroup />
    <Task>
      <Reference Include="" />
      <Using Namespace="" />
      <Code Type="Fragment" Language="cs">
      </Code>
    </Task>
  </UsingTask>
</Project>

Элемент UsingTask в этом примере имеет три атрибута, описывающих задачу, и компилирующую ее фабрику встроенных задач.

  • Атрибут TaskName присваивает задаче имя, в этом случае — DoNothing.

  • Атрибут TaskFactory присваивает имя классу, реализующему фабрику встроенных задач.

  • Атрибут AssemblyFile задает местоположение фабрики встроенных задач.В качестве альтернативного варианта для указания полного имени класса фабрики встроенных задач, который, как правило, расположен в глобальном кэше сборок, можно использовать атрибут AssemblyName.

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

  • Элемент ParameterGroup является необязательным.Если он указан, он объявляет параметры для задачи.Дополнительные сведения о входных и выходных параметрах см. в разделе "Входные и выходные параметры" ниже.

  • Элемент Task описывает и содержит исходный код задачи.

  • Элемент Reference задает ссылки на сборки .NET, используемые в коде.Это аналогично добавлению ссылки на проект в Visual Studio.Атрибут Include задает путь сборки, на которую указывает ссылка.

  • Элемент Using создает список пространств имен, к которым необходимо получить доступ.Это похоже на оператор Using в Visual C#.Атрибут Namespace задает включаемое пространство имен.

Элементы Reference и Using не зависят от языка.Встроенные задачи можно создавать на любом поддерживаемом .NET CodeDom языке, например Visual Basic, Visual C# и JScript.

ПримечаниеПримечание

Элементы, содержащиеся в элементе Task, зависят от фабрики задач, в этом случае — фабрики задач кода.

Dd722601.collapse_all(ru-ru,VS.110).gifЭлемент кода

Последним дочерним элементом, расположенным в элементе Task, является элемент Code.Элемент Code содержит или размещает код, который необходимо скомпилировать в задачу.Содержимое элемента Code зависит от способа написания задачи.

Атрибут Language задает язык, на котором создается код.Допустимые значения: cs для C#, vb для Visual Basic и js для JScript.

Атрибут Type задает тип кода, обнаруженного в элементе Code.

  • Если значение Type равно Class, элемент Code содержит код для класса, наследующего из интерфейса ITask.

  • Если значение Type равно Method, код определяет переопределение метода Execute интерфейса ITask.

  • Если значение Type равно Fragment, код определяет содержимое метода Execute, но не сигнатуру или оператор return.

Сам код отображается, как правило, между маркерами <![CDATA[ и ]]>.Поскольку код находится в разделе CDATA, можно не беспокоиться об исключении зарезервированных знаков, например "<" или ">".

В качестве альтернативного варианта для указания местоположения файла, содержащего код для этой задачи, можно использовать атрибут Source элемента Code.Тип кода в исходном файле должен соответствовать типу, заданному атрибутом Type.Если присутствует атрибут Source, значение Type по умолчанию — Class.Если атрибут Source отсутствует, значение по умолчанию — Fragment.

ПримечаниеПримечание

При определении класса задач в исходном файле имя класса должно соответствовать атрибуту TaskName соответствующего элемента UsingTask.

Hello World

Ниже представлена более сложная встроенная задача.Задача HelloWorld отображает фразу "Hello, world!" на устройстве журнала ошибок по умолчанию, которым, как правило, является системная консоль или окно Вывод Visual Studio.В этом примере элемент Reference указан для наглядности.

<Project ToolsVersion="4.0" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
  <!-- This simple inline task displays "Hello, world!" -->
  <UsingTask
    TaskName="HelloWorld"
    TaskFactory="CodeTaskFactory"
    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
    <ParameterGroup />
    <Task>
      <Reference Include="System.Xml.dll"/>
      <Using Namespace="System"/>
      <Using Namespace="System.IO"/>
      <Code Type="Fragment" Language="cs">
<![CDATA[
// Display "Hello, world!"
Log.LogError("Hello, world!");
]]>
      </Code>
    </Task>
  </UsingTask>
</Project>

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

<Project ToolsVersion="4.0" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="HelloWorld.targets" />
  <Target Name="Hello">
    <HelloWorld />
  </Target>
</Project>

Входные и выходные параметры

Параметры встроенной задачи являются дочерними элементами ParameterGroup.Каждый параметр принимает имя определяющего его элемента.Следующий код определяет параметр Text.

<ParameterGroup>
    <Text />
</ParameterGroup>

Параметры могут иметь один или несколько следующих атрибутов:

  • Required является необязательным атрибутом, значение которого по умолчанию —false.Если значение true, необходимо использовать параметр и присвоить ему значение до вызова задачи.

  • ParameterType является необязательным атрибутом, значение которого по умолчанию —System.String.Он должен быть задан для каждого полного типа, являющегося элементом или значением, которое можно преобразовать в строку и наоборот с помощью System.Convert.ChangeType.(Другими словами, любой тип можно передать во внешнюю задачу и наоборот.)

  • Output является необязательным атрибутом, значение которого по умолчанию —false.Если значение true, параметру следует присвоить значение до возвращения из метода Execute (Выполнить).

Например:

<ParameterGroup>
    <Expression Required="true" />
      <Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
    <Tally ParameterType="System.Int32" Output="true" />
</ParameterGroup>

определяет следующие три параметра:

  • Expression является необходимым входным параметром типа System.String.

  • Files является необходимым входным параметром списка элементов.

  • Tally является выходным параметром типа System.Int32.

Если элемент Code имеет атрибут Type (Fragment или Method), свойства автоматически создаются для каждого параметра.В противном случае свойства необходимо явно объявлять в исходном коде задачи и устанавливать точные соответствия их определений параметров.

Пример

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

<Project xmlns='https://schemas.microsoft.com/developer/msbuild/2003' ToolsVersion="4.0">

  <UsingTask TaskName="TokenReplace" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
    <ParameterGroup>
      <Path ParameterType="System.String" Required="true" />
      <Token ParameterType="System.String" Required="true" />
      <Replacement ParameterType="System.String" Required="true" />
    </ParameterGroup>
    <Task>
      <Code Type="Fragment" Language="cs"><![CDATA[
string content = File.ReadAllText(Path);
content = content.Replace(Token, Replacement);
File.WriteAllText(Path, content);

]]></Code>
    </Task>
  </UsingTask>

  <Target Name='Demo' >
    <TokenReplace Path="C:\Project\Target.config" Token="$MyToken$" Replacement="MyValue"/>
  </Target>
</Project>

См. также

Задачи

Пошаговое руководство. Создание встроенной задачи

Основные понятия

Задачи MSBuild