任务写入
任务提供在生成过程中运行的代码。 任务包含在目标中。 MSBuild 附带了典型任务的库,还可以创建自己的任务。 有关 MSBuild 附带的任务库的详细信息,请参阅 任务参考。
任务
任务示例包括 复制(复制一个或多个文件),MakeDir(创建目录),Csc(编译 C# 源代码文件)。 每个任务都实现为实现 ITask 接口的 .NET 类,该接口在 Microsoft.Build.Framework.dll 程序集中定义。
实现任务时可以使用两种方法:
直接实现 ITask 接口。
从 Microsoft.Build.Utilities.dll 程序集中定义的帮助程序类 Task 中派生类。 任务实现 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) 注册的。
如果任务具有特定于运行时的依赖项,则必须通过在其 UsingTask 中指示 Architecture
和/或 Runtime
来通知 MSBuild 应在特定环境中运行任务。
MSBuild 文件 Microsoft.Common.tasks 是一个项目文件,其中包含 UsingTask
元素列表,这些元素注册了 MSBuild 提供的所有任务。 生成任何项目时,将自动包含此文件。 如果在 Microsoft.Common.tasks 中注册的任务也在当前项目文件中注册,则当前项目文件优先,因此可以使用自己的具有相同名称的任务替代默认任务。
提示
可以通过查看 Microsoft.Common.tasks中的内容,了解随特定版本 MSBuild 提供的任务列表。
从任务引发事件
如果任务派生自 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]
属性由 Microsoft.Build.Framework 命名空间中的 RequiredAttribute 定义。
MSBuild 如何调用任务
调用任务时,MSBuild 首先实例化任务类,然后调用该对象的属性设置器,以为项目文件中任务元素中设置的任务参数进行设定。 如果任务元素未指定参数,或者元素中指定的表达式的计算结果为空字符串,则不会调用属性 setter。
例如,在该项目中
<Project>
<Target Name="InvokeCustomTask">
<CustomTask Input1=""
Input2="$(PropertyThatIsNotDefined)"
Input3="value3" />
</Target>
</Project>
仅调用 Input3
的资源库。
任务不应依赖于参数属性 setter 调用的任何相对顺序。
任务参数类型
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>
相关内容
- 创建自定义任务
- 使用 MSBuild 创建 REST API 客户端
- 任务参考