Compartilhar via


Gravar tarefas para o MSBuild

As tarefas estão contidas em destinos do MSBuild e fornecem o código executado durante o processo de build. O MSBuild inclui uma biblioteca de tarefas típicas e você também pode criar suas próprias tarefas. Para obter mais informações sobre a biblioteca de tarefas que o MSBuild inclui, consulte a referência de tarefa do MSBuild.

Pré-requisitos

Um projeto do Visual Studio criado com o MSBuild.

Tarefas

Exemplos de tarefas do MSBuild incluem Copy, que copia um ou mais arquivos, MakeDir, que cria um diretório, e Csc, que compila arquivos de código-fonte C#. Cada tarefa é implementada como uma classe .NET que implementa a ITask interface definida no assemblyMicrosoft.Build.Framework.dll .

Você pode usar qualquer uma das seguintes abordagens ao implementar uma tarefa:

  • Implemente a interface ITask diretamente.

  • Derive a classe da classe auxiliar Task, definida no assembly Microsoft.Build.Utilities.dll. Task implementa ITask e fornece implementações padrão de alguns membros ITask. O registro em log também é mais fácil.

Em ambos os casos, você deve adicionar um método à sua classe chamada Execute, que é chamada quando a tarefa é executada. Esse método não usa parâmetros e retorna um valor Boolean: true se a tarefa foi bem-sucedida ou false se falhou. O exemplo a seguir mostra uma tarefa que não executa nenhuma ação, é concluída com êxito e retorna true.

using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace MyTasks
{
    public class SimpleTask : Task
    {
        public override bool Execute()
        {
            return true;
        }
    }
}

O seguinte arquivo de projeto do MSBuild executa a tarefa anterior:

<Project>
    <Target Name="MyTarget">
        <SimpleTask />
    </Target>
</Project>

Quando as tarefas são executadas, elas também podem receber entradas do arquivo de projeto se você criar propriedades do .NET na classe de tarefa. O MSBuild define essas propriedades imediatamente antes de chamar o método Execute da tarefa. Para criar uma propriedade de cadeia de caracteres, use o código da tarefa, como o seguinte exemplo:

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; }
    }
}

O arquivo de projeto a seguir executa essa tarefa e define MyProperty para o valor fornecido.

<Project>
   <Target Name="MyTarget">
      <SimpleTask MyProperty="Value for MyProperty" />
   </Target>
</Project>

Como o MSBuild invoca tarefas

Quando o MSBuild invoca uma tarefa, ele primeiro cria uma instância da classe de tarefa e, em seguida, chama os definidores de propriedade desse objeto para parâmetros de tarefa que são definidos no elemento da tarefa no arquivo do projeto. Se o elemento de tarefa não especificar um parâmetro ou se a expressão especificada no elemento for avaliada como uma cadeia de caracteres vazia, o setter de propriedade não será chamado.

Por exemplo, no projeto a seguir, apenas o setter para Input3 é chamado.

<Project>
 <Target Name="InvokeCustomTask">
  <CustomTask Input1=""
              Input2="$(PropertyThatIsNotDefined)"
              Input3="value3" />
 </Target>
</Project>

Uma tarefa não deve depender de nenhuma ordem relativa de invocação do setter de propriedade do parâmetro.

Tipos de parâmetro de tarefa

O MSBuild manipula nativamente propriedades dos tipos string, bool, ITaskItem e ITaskItem[]. Se uma tarefa aceitar um parâmetro de um tipo diferente, o MSBuild invocará ChangeType para converter de string, com todas as referências de propriedade e item expandidas, para o tipo de destino. Se a conversão falhar para qualquer parâmetro de entrada, o MSBuild emitirá um erro e não chamará o método da Execute() tarefa.

Registrar tarefas

Para executar uma tarefa, o MSBuild deve saber como localizar e executar o assembly que contém a classe de tarefa. As tarefas são registradas usando o elemento UsingTask (MSBuild).

Se sua tarefa tiver dependências específicas de runtime, você deverá direcionar o MSBuild para executar a tarefa em um ambiente específico, indicando os atributos `Architecture` ou `Runtime` no elemento `UsingTask`. Para obter mais informações, consulte atributos UsingTask e parâmetros de tarefa.

O arquivo MSBuild Microsoft.Common.tasks é um arquivo de projeto que lista os UsingTask elementos que registram todas as tarefas fornecidas com o MSBuild. Esse arquivo é incluído automaticamente quando o MSBuild compila qualquer projeto. Se uma tarefa registrada em Microsoft.Common.tasks também estiver registrada no arquivo de projeto atual, o arquivo de projeto atual terá precedência, para que você possa substituir uma tarefa padrão com sua própria tarefa com o mesmo nome.

Dica

Você pode ver uma lista das tarefas fornecidas com uma versão específica do MSBuild exibindo o conteúdo do arquivo Microsoft.Common.tasks .

Exigir que as propriedades da tarefa sejam definidas

Você pode marcar determinadas propriedades de tarefa conforme necessário, portanto, qualquer arquivo de projeto que executa a tarefa deve definir valores para essas propriedades ou o build falhará. Aplique o atributo [Required] à propriedade .NET em sua tarefa da seguinte maneira:

[Required]
public string RequiredProperty { get; set; }

O atributo [Required] é definido por RequiredAttribute no namespace Microsoft.Build.Framework.

Gerar eventos a partir de uma tarefa

Se a sua tarefa derivar da Task classe de ajuda, você poderá usar qualquer um dos seguintes métodos auxiliares na Task classe para gerar eventos que são capturados e exibidos por todos os registradores registrados.

public override bool Execute()
{
    Log.LogError("messageResource1", "1", "2", "3");
    Log.LogWarning("messageResource2");
    Log.LogMessage(MessageImportance.High, "messageResource3");
    ...
}

Se sua tarefa implementar ITask diretamente, você ainda poderá gerar esses eventos, mas deverá usar a interface IBuildEngine. O exemplo a seguir mostra uma tarefa que implementa ITask e gera um evento personalizado.

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;
    }
}

Empacotar a tarefa

A maneira recomendada de distribuir uma tarefa está em um pacote NuGet. O pacote precisa agrupar todas as dependências. Para obter um tutorial que orienta você na criação de uma tarefa personalizada, consulte Criar um pacote NuGet.

Exemplo 1

A classe C# a seguir demonstra uma tarefa derivada da Task classe auxiliar. Essa tarefa retorna true, indicando que ela foi bem-sucedida.

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;
        }
    }
}

Exemplo 2

A classe C# a seguir demonstra uma tarefa implementando a ITask interface. Essa tarefa retorna true, indicando que ela foi bem-sucedida.

using System;
using Microsoft.Build.Framework;

namespace SimpleTask2
{
    public class SimpleTask2: ITask
    {
        //When implementing the ITask interface, it's 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's 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 does its work.
            return true;
        }
    }
}

Exemplo 3

Essa classe C# demonstra uma tarefa que deriva da classe auxiliar Task. A tarefa possui uma propriedade de string necessária e gera um evento exibido por todos os registradores de log registrados.

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;
        }
    }
}

Exemplo 4

O exemplo a seguir mostra um arquivo de projeto que invoca a tarefa de exemplo anterior. SimpleTask3

<Project>
    <UsingTask TaskName="SimpleTask3.SimpleTask3"
        AssemblyFile="SimpleTask3\bin\debug\simpletask3.dll"/>

    <Target Name="MyTarget">
        <SimpleTask3 MyProperty="Hello!"/>
    </Target>
</Project>