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

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

В этом пошаговом руководстве показано, как создать и выполнить следующие встроенные задачи:

  • задача, которая не имеет входных или выходных параметров;

  • задача, которая имеет один входной параметр и не имеет выходных параметров;

  • задача с двумя входными параметрами и одним выходным параметром, возвращающим свойство MSBuild;

  • задача с двумя входными параметрами и одним выходным параметром, возвращающим элемент MSBuild.

Чтобы создать и выполнить задачи, следует использовать Visual Studio и окно командной строки Visual Studio, как показано ниже.

  1. Создайте файл проекта MSBuild с помощью Visual Studio.

  2. Измените файл проекта в Visual Studio, чтобы создать встроенную задачу.

  3. Используйте окно командной строки, чтобы выполнить построение проекта и проверить результаты.

Создание и изменение проекта MSBuild

Система проектов Visual Studio основана на MSBuild. Поэтому вы можете создать файл проекта построения с помощью Visual Studio. В этом разделе создается файл проекта Visual C#. (Вместо него можно создать файл проекта Visual Basic. В контексте данного руководства различия между двумя файлами проекта незначительны.)

Создание и изменение файла проекта

  1. В Visual Studio создайте новый проект с помощью шаблона приложения C# Windows Forms. В поле Имя введите InlineTasks. Укажите расположение для решения, например D:\. Выберите Создать каталог для решения, снимите флажок Добавить в систему управления версиями, а для параметра Имя решения укажите InlineTasks.

  2. Нажмите кнопку ОК, чтобы создать файл проекта.

  3. В обозревателе решений щелкните правой кнопкой мыши узел проекта InlineTasks и выберите команду Выгрузить проект.

  4. Еще раз щелкните правой кнопкой мыши узел проекта, а затем выберите Изменить InlineTasks.csproj.

    Файл проекта откроется в редакторе кода.

Добавление простой задачи Hello

Теперь добавьте в файл проекта простую задачу, отображающую сообщение "Hello, world!". Также добавьте целевой объект по умолчанию, TestBuild, который будет вызывать задачу.

Добавление простой задачи Hello

  1. В корневом узле Project измените атрибут DefaultTargets на TestBuild. Итоговый узел Project должен выглядеть следующим образом:

    <Project ToolsVersion="4.0" DefaultTargets="TestBuild" xmlns="http://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(MessageImportance.High, "Hello, world!");
        </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 без параметров команды и нажмите клавишу ВВОД. По умолчанию в результате создается файл InlineTasks.csproj и выполняется обработка стандартного целевого объекта TestBuild, вызывающего задачу Hello.

  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(MessageImportance.High, Text);
        </Code>
      </Task>
    </UsingTask>
    <Target Name="TestBuild">
      <Echo Text="Greetings!" />
    </Target>
    
  2. В окне командной строки введите msbuild без параметров команды и нажмите клавишу ВВОД. По умолчанию в результате обрабатывается стандартный целевой объект TestBuild, вызывающий задачу Echo.

  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 без параметров команды и нажмите клавишу ВВОД. По умолчанию в результате обрабатывается стандартный целевой объект TestBuild, вызывающий задачу Echo.

  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 без параметров команды и нажмите клавишу ВВОД. По умолчанию в результате обрабатывается стандартный целевой объект TestBuild, вызывающий задачу RegX.

  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[

 if (Files.Length > 0)
 {
     // Your code goes here.
 }
 ]]>
</Code>