演练:创建内联任务

MSBuild 任务通常是通过编译可实现 ITask 接口的类来创建的。 从 .NET Framework 4 版开始,您可以在项目文件中创建内联任务, 而不必创建单独的程序集来承载任务。 有关更多信息,请参见 MSBuild 内联任务

本演练演示如何创建和运行以下内联任务:

  • 没有输入或输出参数的任务。

  • 具有一个输入参数,但没有输出参数的任务。

  • 具有两个输入参数,以及一个可返回 MSBuild 属性的输出参数的任务。

  • 具有两个输入参数,以及一个可返回 MSBuild 项的输出参数的任务。

要创建并运行任务,请使用 Visual Studio 和**“Visual Studio 命令提示”**窗口,如下所示:

  • 使用 Visual Studio 创建 MSBuild 项目文件。

  • 在 Visual Studio 中修改项目文件以创建内联任务。

  • 使用**“命令提示符窗口”**生成项目,并检查结果。

创建和修改 MSBuild 项目

Visual Studio 项目系统以 MSBuild 为基础。 因此,可以使用 Visual Studio 来创建生成项目文件。 在本节中,将创建一个 Visual C# 项目文件。 (可以改为创建 Visual Basic 项目文件。 在此教程的上下文中,这两种项目文件的差别很小。)

创建和修改项目文件

  1. 在 Visual Studio 中的**“文件”菜单上,单击“新建”,然后单击“项目”**。

  2. 在**“新建项目”对话框中,选择 Visual C# 项目类型,再选择“Windows 窗体应用程序”模板。 在“名称”框中键入 InlineTasks。 键入解决方案的“位置”,例如,D:\。 确保“创建解决方案的目录”处于选定状态,“添加到源代码管理”处于清除状态,并且“解决方案名称”**为 InlineTasks。

    单击**“确定”**创建项目文件。

  3. 在**“解决方案资源管理器”中,右击 InlineTasks 项目节点,然后单击“卸载项目”**。

  4. 再次右击该项目节点,然后单击**“编辑 InlineTasks.csproj”**。

    此时,该项目文件将出现在代码编辑器中。

添加基本的 Hello 任务

现在,向项目文件中添加一个显示消息“Hello, world!”的基本任务。另外添加一个用于调用该任务的默认 TestBuild 目标。

添加基本的 hello 任务

  1. 在根 Project 节点中,将 DefaultTargets 特性更改为 TestBuild。生成的 Project 节点应类似于以下示例:

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

  2. 将以下内联任务和目标添加到项目文件中 </Project> 标记的前面。

    <UsingTask TaskName="Hello" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
      <ParameterGroup />
      <Task>
        <Code Type="Fragment" Language="cs">
          Log.LogMessage("Hello, world!", MessageImportance.High);
        </Code>
      </Task>
    </UsingTask>
    <Target Name="TestBuild">
      <Hello />
    </Target>
    
  3. 保存项目文件。

此代码将创建一个内联任务,该任务名为 Hello,并且没有参数、引用或 Using 语句。 Hello 任务只包含一行代码,用于在默认日志记录设备(通常为控制台窗口)上显示 hello 消息。

运行 Hello 任务

使用**“命令提示符窗口”**运行 MSBuild,以构建 Hello 任务并处理调用该任务的 TestBuild 目标。

运行 Hello 任务

  1. 依次单击**“开始”“所有程序”,然后找到“Visual Studio 工具”文件夹并单击“Visual Studio 命令提示”**。

  2. 在**“命令提示符窗口”**中,找到包含项目文件的文件夹,本例中为 D:\InlineTasks\InlineTasks\。

  3. 键入不带命令开关的 msbuild,然后按 Enter。 默认情况下,此操作将生成 InlineTasks.csproj 文件,并处理调用 Hello 任务的默认目标 TestBuild。

  4. 在**“命令提示符窗口”**中检查输出。 您应会看到以下行:

    Hello, world!

    备注

    如果看不到 hello 消息,请尝试再次保存项目文件,然后运行 Hello 任务。

通过交替显示代码编辑器和**“命令提示符窗口”**,您可以更改项目文件并快速查看结果。

定义 Echo 任务

创建一个内联任务,该任务接受字符串参数,并在默认日志记录设备上显示字符串。

定义 Echo 任务

  1. 在代码编辑器中,使用以下代码替换 Hello 任务和 TestBuild 目标。

    <UsingTask TaskName="Echo" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
      <ParameterGroup>
        <Text Required="true" />
      </ParameterGroup>
      <Task>
        <Code Type="Fragment" Language="cs">
          Log.LogMessage(Text, MessageImportance.High);
        </Code>
      </Task>
    </UsingTask>
    <Target Name="TestBuild">
      <Echo Text="Greetings!" />
    </Target>
    
  2. 在**“命令提示符窗口”**中,键入不带命令开关的 msbuild,然后按 Enter。 默认情况下,此操作将处理调用 Echo 任务的默认目标 TestBuild。

  3. 在**“命令提示符窗口”**中检查输出。 您应会看到以下行:

    Greetings!

此代码将定义一个内联任务,该任务名为 Echo,并且只有一个必需的输入参数 Text。 默认情况下,参数的类型为 System.String。 Text 参数的值是在 TestBuild 目标调用 Echo 任务时设置的。

定义 Adder 任务

创建一个内联任务,该任务将添加两个整数参数,并将这些参数的和作为 MSBuild 属性发出。

定义 Adder 任务

  1. 在代码编辑器中,使用以下代码替换 Echo 任务和 TestBuild 目标。

    <UsingTask TaskName="Adder" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
      <ParameterGroup>
        <A ParameterType="System.Int32" Required="true" />
        <B ParameterType="System.Int32" Required="true" />
        <C ParameterType="System.Int32" Output="true" />
      </ParameterGroup>
      <Task>
        <Code Type="Fragment" Language="cs">
          C = A + B;
        </Code>
      </Task>
    </UsingTask>  
    <Target Name="TestBuild">
      <Adder A="4" B="5">
        <Output PropertyName="Sum" TaskParameter="C" />
      </Adder>
      <Message Text="The sum is $(Sum)" Importance="High" />
    </Target>
    
  2. 在**“命令提示符窗口”**中,键入不带命令开关的 msbuild,然后按 Enter。 默认情况下,此操作将处理调用 Echo 任务的默认目标 TestBuild。

  3. 在**“命令提示符窗口”**中检查输出。 您应会看到以下行:

    The sum is 9

此代码将定义一个内联任务,该任务名为 Adder,并具有两个必需的整数输入参数 A 和 B,以及一个整数输出参数 C。 Adder 任务将添加两个输入参数,并在输出参数中返回和。 和将作为 MSBuild 属性 Sum 发出。 输入参数的值是在 TestBuild 目标调用 Adder 任务时设置的。

定义 RegX 任务

创建一个内联任务,该任务接受项组和正则表达式,并返回文件内容与表达式匹配的所有项的列表。

定义 RegX 任务

  1. 在代码编辑器中,使用以下代码替换 Adder 任务和 TestBuild 目标。

    <UsingTask TaskName="RegX" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
      <ParameterGroup>
        <Expression Required="true" />
        <Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
        <Result ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" />
      </ParameterGroup>
      <Task>
        <Using Namespace="System.Text.RegularExpressions"/>
        <Code Type="Fragment" Language="cs">
    <![CDATA[
          if (Files.Length > 0)
          {
            Result = new TaskItem[Files.Length];
            for (int i = 0; i < Files.Length; i++)
            {
              ITaskItem item = Files[i];
              string path = item.GetMetadata("FullPath");
              using(StreamReader rdr = File.OpenText(path))
              {
                if (Regex.Match(rdr.ReadToEnd(), Expression).Success)
                {
                  Result[i] = new TaskItem(item.ItemSpec);
                }
              }
            }
          }
    ]]>
        </Code>
      </Task>
    </UsingTask>  
    <Target Name="TestBuild">
      <RegX Expression="public|protected" Files="@(Compile)">
        <Output ItemName="MatchedFiles" TaskParameter="Result" />
      </RegX>
      <Message Text="Input files: @(Compile)" Importance="High" />
      <Message Text="Matched files: @(MatchedFiles)" Importance="High" />
    </Target>
    
  2. 在**“命令提示符窗口”**中,键入不带命令开关的 msbuild,然后按 Enter。 默认情况下,此操作将处理调用 RegX 任务的默认目标 TestBuild。

  3. 在**“命令提示符窗口”**中检查输出。 您应会看到以下各行:

    Input files: Form1.cs;Form1.Designer.cs;Program.cs;Properties\AssemblyInfo.cs;Properties\Resources.Designer.cs;Properties\Settings.Designer.cs

    Matched files: Form1.cs;Form1.Designer.cs;Properties\Settings.Designer.cs

此代码将定义一个内联任务,该任务名为 RegX,并且具有以下三个参数:

  • Expression 是必需的字符串输入参数,其值是要匹配的正则表达式。 在本例中,表达式匹配单词“public”或“protected”。

  • Files 是必需的项列表输入参数,其值是要针对匹配进行搜索的文件的列表。 在本例中,Files 设置为 Compile 项,该项将列出项目源文件。

  • Result 是输出参数,其值是内容与正则表达式匹配的文件的列表。

输入参数的值是在 TestBuild 目标调用 RegX 任务时设置的。 RegX 任务将读取每个文件,并返回与正则表达式匹配的文件的列表。 此列表将作为 Result 输出参数返回,后者将以 MSBuild 项 MatchedFiles 的形式发出。

处理保留字符

MSBuild 分析器以 XML 的形式处理内联任务。 系统将检测并处理在 XML 中具有保留意义的字符(例如,“<”和“>”),就好像这些字符是 XML(而不是 .NET 源代码)一样。 要将保留字符包括在诸如 Files.Length > 0 等代码表达式中,请编写 Code 元素以使其内容包含在 CDATA 表达式中,如下所示:

<Code Type="Fragment" Language="cs">

<![CDATA[

// Your code goes here.

]]>

</Code>

请参见

概念

MSBuild 内联任务

MSBuild 任务

MSBuild 目标