Написание задач
Задачи предоставляют код, выполняемый во время процесса сборки. Задачи содержатся в целевых объектах. Библиотека типичных задач включается в MSBuild, и вы также можете создавать собственные задачи. Более подробную информацию о библиотеке задач, включенных в MSBuild, можно найти в справочнике по задачам.
Задачи
Примерами задач являются Копия, который копирует один или несколько файлов, MakeDir, который создает каталог, и Csc, который компилирует файлы исходного кода на C#. Каждая задача реализуется как класс .NET, реализующий интерфейс ITask, который определен в сборке Microsoft.Build.Framework.dll.
Существует два подхода, которые можно использовать при реализации задачи:
Реализуйте интерфейс ITask напрямую.
Наследуйте свой класс от вспомогательного класса Task, который определён в сборке Microsoft.Build.Utilities.dll. Задача реализует интерфейс ITask и предоставляет реализации некоторых членов интерфейса ITask по умолчанию. Кроме того, ведение журнала проще.
В обоих случаях необходимо добавить в класс метод с именем Execute
, который вызывается при выполнении задачи. Этот метод не принимает параметров и возвращает значение Boolean
: true
, если задача завершилась успешно или false
, если она завершилась ошибкой. В следующем примере показана задача, которая не выполняет никаких действий и завершается успешно (возвращается true
).
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace MyTasks
{
public class SimpleTask : Task
{
public override bool Execute()
{
return true;
}
}
}
Следующий файл проекта выполняет эту задачу:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MyTarget">
<SimpleTask />
</Target>
</Project>
При выполнении задач они также могут получать входные данные из файла проекта при создании свойств .NET в классе задач. MSBuild задает эти свойства непосредственно перед вызовом метода Execute
задачи. Чтобы создать строковое свойство, используйте код задачи, например:
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace MyTasks
{
public class SimpleTask : Task
{
public override bool Execute()
{
return true;
}
public string MyProperty { get; set; }
}
}
Следующий файл проекта запускает эту задачу и задает MyProperty
заданному значению:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MyTarget">
<SimpleTask MyProperty="Value for MyProperty" />
</Target>
</Project>
Регистрация задач
Если проект будет выполнять задачу, MSBuild должен знать, как найти и запустить сборку, содержащую класс задач. Задачи регистрируются с помощью элемента UsingTask (MSBuild).
Если ваша задача имеет зависимости, зависящие от среды выполнения, необходимо сообщить MSBuild, что ее нужно выполнять в конкретной среде, указав Architecture
и/или Runtime
вUsingTask.
Файл MSBuild Microsoft.Common.tasks — это файл проекта, содержащий список элементов UsingTask
, которые регистрируют все задачи, предоставляемые с помощью MSBuild. Этот файл автоматически включается при создании любого проекта. Если задача, зарегистрированная в Microsoft.Common.tasks, также зарегистрирована в текущем файле проекта, текущий файл проекта имеет приоритет, поэтому можно переопределить задачу по умолчанию с собственным именем.
Совет
Список задач, предоставляемых определенной версией MSBuild, можно увидеть в содержимом Microsoft.Common.tasks.
Создание событий из задачи
Если ваша задача происходит от класса-помощника Task, вы можете использовать любой из следующих методов в классе Task, чтобы вызывать события, которые будут обработаны и отображены любыми зарегистрированными средствами логирования:
public override bool Execute()
{
Log.LogError("messageResource1", "1", "2", "3");
Log.LogWarning("messageResource2");
Log.LogMessage(MessageImportance.High, "messageResource3");
...
}
Если задача реализует ITask напрямую, вы все равно можете вызвать такие события, но необходимо использовать интерфейс IBuildEngine. В следующем примере показана задача, реализующая ITask и создающая настраиваемое событие:
public class SimpleTask : ITask
{
public IBuildEngine BuildEngine { get; set; }
public override bool Execute()
{
TaskEventArgs taskEvent =
new TaskEventArgs(BuildEventCategory.Custom,
BuildEventImportance.High, "Important Message",
"SimpleTask");
BuildEngine.LogBuildEvent(taskEvent);
return true;
}
}
Требовать задания параметров задачи
Вы можете пометить определенные свойства задачи как обязательные, чтобы любой файл проекта, выполняющий эту задачу, должен был задать значения для этих свойств, иначе сборка завершится ошибкой. Примените атрибут [Required]
к свойству .NET в задаче следующим образом:
[Required]
public string RequiredProperty { get; set; }
Атрибут [Required]
определяется RequiredAttribute в пространстве имен Microsoft.Build.Framework.
Как MSBuild вызывает задачу
При вызове задачи MSBuild сначала создает экземпляр класса задач, а затем вызывает методы задания свойств этого объекта для параметров задачи, заданных в элементе задачи в файле проекта. Если элемент задачи не задает параметр или если выражение, указанное в элементе, оценивается как пустая строка, метод задания свойств не вызывается.
Например, в проекте
<Project>
<Target Name="InvokeCustomTask">
<CustomTask Input1=""
Input2="$(PropertyThatIsNotDefined)"
Input3="value3" />
</Target>
</Project>
вызывается только сеттер для Input3
.
Задача не должна зависеть от относительного порядка вызова набора свойств параметров.
Типы параметров задачи
MSBuild изначально обрабатывает свойства типа string
, bool
, ITaskItem
и ITaskItem[]
. Если задача принимает параметр другого типа, MSBuild вызывает ChangeType для преобразования из string
(со всеми развернутыми ссылками на свойства и элементы) в требуемый тип. Если преобразование завершается ошибкой для любого входного параметра, MSBuild выдает ошибку и не вызывает метод Execute()
задачи.
Упаковка задачи
Рекомендуемый способ распространения задачи — в пакете NuGet. Пакет должен включить все зависимости. Этот вопрос подробно объясняется в руководстве, которое пошагово проведет вас через создание пользовательской задачи. См. Создание пакета NuGet.
Пример 1
Описание
Следующий класс C# демонстрирует задачу, полученную из вспомогательного класса Task. Эта задача возвращает true
, указывая, что она выполнена успешно.
Код
using System;
using Microsoft.Build.Utilities;
namespace SimpleTask1
{
public class SimpleTask1: Task
{
public override bool Execute()
{
// This is where the task would presumably do its work.
return true;
}
}
}
Пример 2
Описание
Следующий класс C# демонстрирует задачу реализации интерфейса ITask. Эта задача возвращает true
, указывая, что она выполнена успешно.
Код
using System;
using Microsoft.Build.Framework;
namespace SimpleTask2
{
public class SimpleTask2: ITask
{
//When implementing the ITask interface, it is necessary to
//implement a BuildEngine property of type
//Microsoft.Build.Framework.IBuildEngine. This is done for
//you if you derive from the Task class.
public IBuildEngine BuildEngine { get; set; }
// When implementing the ITask interface, it is necessary to
// implement a HostObject property of type object.
// This is done for you if you derive from the Task class.
public object HostObject { get; set; }
public bool Execute()
{
// This is where the task would presumably do its work.
return true;
}
}
}
Пример 3
Описание
Этот класс C# демонстрирует задачу, наследуемую от вспомогательного класса Task. Он имеет обязательное строковое свойство и вызывает событие, отображаемое всеми зарегистрированными средствами ведения журнала.
Код
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace SimpleTask3
{
public class SimpleTask3 : Task
{
private string myProperty;
// The [Required] attribute indicates a required property.
// If a project file invokes this task without passing a value
// to this property, the build will fail immediately.
[Required]
public string MyProperty
{
get
{
return myProperty;
}
set
{
myProperty = value;
}
}
public override bool Execute()
{
// Log a high-importance comment
Log.LogMessage(MessageImportance.High,
"The task was passed \"" + myProperty + "\".");
return true;
}
}
}
Пример 4
Описание
В следующем примере показан файл проекта, вызывающий предыдущую примерную задачу SimpleTask3.
Код
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="SimpleTask3.SimpleTask3"
AssemblyFile="SimpleTask3\bin\debug\simpletask3.dll"/>
<Target Name="MyTarget">
<SimpleTask3 MyProperty="Hello!"/>
</Target>
</Project>
Связанное содержимое
- Создание пользовательской задачи
- Создание клиента REST API с помощью MSBuild
- Справочник по задачам