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 特性指定内联任务工厂类的完全限定名,该类通常位于全局程序集缓存 (GAC) 中。

DoNothing 任务的其余元素为空,提供这些元素的目的是为了阐释内联任务的顺序和结构。本主题后面提供了一个功能更为全面的示例。

  • ParameterGroup 元素是可选的。如果指定该元素,它将声明任务的参数。有关输入和输出参数的更多信息,请参见本主题后面的“输入和输出参数”。

  • Task 元素描述并包含任务源代码。

  • Reference 元素指定对代码中所使用的 .NET 程序集的引用。这相当于在 Visual Studio 中添加对项目的引用。Include 特性指定所引用的程序集的路径。

  • Using 元素列出您希望访问的命名空间。这类似于 Visual C# 中的 Using 语句。Namespace 特性指定要包括的命名空间。

Reference 和 Using 元素与语言无关。可以用任何一种支持的 .NET CodeDom 语言(例如,Visual Basic、Visual C# 和 JScript)编写内联任务。

说明说明

Task 元素中包含的元素特定于任务工厂(本例中为代码任务工厂)。

Dd722601.collapse_all(zh-cn,VS.110).gifCode 元素

要出现在 Task 元素内的最后一个子元素是 Code 元素。Code 元素包含或查找要编译到任务中的代码。放在 Code 元素的内容取决于您希望如何编写任务。

Language 特性指定编写代码所采用的语言。可接受的值包括 cs(表示 C#)、vb(表示 Visual Basic)和 js(表示 JScript)。

Type 特性指定在 Code 元素中找到的代码的类型。

  • 如果 Type 的值为 Class,则 Code 元素包含派生自 ITask 接口的类的代码。

  • 如果 Type 的值为 Method,则代码定义 ITask 接口的 Execute 方法的重写。

  • 如果 Type 的值为 Fragment,则代码定义 Execute 方法的内容,但不定义签名或 return 语句。

代码本身通常出现在 <![CDATA[ 标记和 ]]> 标记之间。由于代码位于 CDATA 部分中,因此您不必担心转义保留字符(例如,“<”或“>”)。

或者,您可以使用 Code 元素的 Source 特性指定包含任务代码的文件的位置。源文件中代码的类型必须为 Type 特性所指定的类型。如果存在 Source 特性,则 Type 的默认值为 Class。如果 Source 不存在,则默认值为 Fragment。

说明说明

在源文件中定义任务类时,类名必须与对应 UsingTask 元素的 TaskName 特性一致。

Hello World

下面是一个功能更全面的内联任务。HelloWorld 任务在默认的错误日志记录设备(通常为系统控制台或 Visual Studio 的**“输出”**窗口)上显示“Hello, World!”。示例中包括的 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 任务