Écriture de tâches

Les tâches fournissent le code exécuté pendant le processus de génération. Les tâches sont contenues dans les cibles. Une bibliothèque de tâches types est incluse dans MSBuild. De plus, vous pouvez créer vos propres tâches. Pour plus d’informations sur la bibliothèque de tâches incluse dans MSBuild, consultez Informations de référence sur les tâches.

Tâches

Voici quelques exemples de tâches : Copy, qui copie des fichiers, MakeDir, qui crée des répertoires et Csc, qui compile des fichiers de code source C#. Chaque tâche est implémentée en tant que classe .NET implémentant l’interface ITask, définie dans l’assembly Microsoft.Build.Framework.dll.

Vous pouvez adopter deux approches lors de l’implémentation d’une tâche :

  • implémenter directement l’interface ITask ;

  • dériver votre classe de la classe d’assistance, Task, définie dans l’assembly Microsoft.Build.Utilities.dll. La tâche implémente ITask et fournit des implémentations par défaut de certains membres ITask. De plus, la journalisation est plus facile.

Dans les deux cas, vous devez ajouter à votre classe une méthode nommée Execute, qui est la méthode appelée lorsque la tâche s’exécute. Cette méthode n’accepte aucun paramètre et retourne une valeur Boolean : true si la tâche a réussi ou false si elle a échoué. L’exemple suivant montre une tâche qui n’effectue aucune action et se termine avec succès (retourne true).

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

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

Le fichier projet suivant exécute cette tâche :

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="MyTarget">
        <SimpleTask />
    </Target>
</Project>

Lorsque les tâches sont exécutées, elles peuvent également recevoir des entrées du fichier projet si vous créez des propriétés .NET dans la classe de tâche. MSBuild définit ces propriétés immédiatement avant l’appel de la méthode Execute de la tâche. Pour créer une propriété de type chaîne, utilisez du code de tâche tel que celui-ci :

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

Le fichier projet suivant exécute cette tâche et définit MyProperty sur la valeur donnée :

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Target Name="MyTarget">
      <SimpleTask MyProperty="Value for MyProperty" />
   </Target>
</Project>

Inscrire des tâches

Si un projet va exécuter une tâche, MSBuild doit savoir comment localiser et exécuter l’assembly qui contient la classe de tâche. Les tâches sont inscrites à l’aide de l’élément UsingTask (MSBuild).

Si votre tâche a des dépendances spécifiques au runtime, vous devez demander à MSBuild d’exécuter la tâche dans un environnement spécifique par en indiquant Architecture et/ou Runtime dans son UsingTask.

Le fichier MSBuild Microsoft.Common.Tasks est un fichier projet qui contient une liste d’éléments UsingTask qui inscrivent toutes les tâches fournies avec MSBuild. Ce fichier est inclus automatiquement lors de la génération d’un projet. Si une tâche inscrite dans Microsoft.Common.tasks est également inscrite dans le fichier projet actuel, ce dernier est prioritaire. Autrement dit, vous pouvez remplacer une tâche par défaut par votre propre tâche du même nom.

Conseil

Vous pouvez voir la liste des tâches qui sont fournies avec une version spécifique de MSBuild en affichant le contenu de Microsoft.Common.tasks.

Déclencher des événements à partir d’une tâche

Si votre tâche dérive de la classe d’assistance Task, vous pouvez utiliser l’une des méthodes d’assistance suivantes dans la classe Task pour déclencher des événements qui seront interceptés et affichés par tous les journaux inscrits :

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

Si votre tâche implémente ITask directement, vous pouvez également déclencher ces événements, mais vous devez pour cela utiliser l’interface IBuildEngine. L’exemple suivant montre une tâche qui implémente ITask et déclenche un événement personnalisé :

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

Exiger la définition de paramètres de tâche

Vous pouvez marquer certaines propriétés de tâche comme étant « obligatoires ». De cette façon, si les fichiers projet qui exécutent la tâche ne définissent pas les valeurs de ces propriétés, la génération échoue. Dans votre tâche, appliquez l’attribut [Required] à la propriété .NET de la manière suivante :

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

L’attribut [Required] est défini par RequiredAttribute dans l’espace de noms Microsoft.Build.Framework.

Comment MSBuild appelle une tâche

Lors de l’appel d’une tâche, MSBuild instancie d’abord la classe de tâche, puis appelle les setters de propriétés de cet objet pour les paramètres de tâche définis dans l’élément de tâche dans le fichier projet. Si l’élément de tâche ne spécifie pas de paramètre ou si l’expression spécifiée dans l’élément prend la valeur d’une chaîne vide, l’ensemble de propriétés n’est pas appelé.

Par exemple, dans le projet

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

seul le setter pour Input3 est appelé.

Une tâche ne doit pas dépendre d’un ordre relatif d’appels de setters de paramètres-propriétés.

Types de paramètres de tâche

MSBuild gère en mode natif les propriétés de type string, bool, ITaskItem et ITaskItem[]. Si une tâche accepte un paramètre d’un autre type, MSBuild appelle ChangeType pour convertir de string (avec toutes les références de propriété et d’élément développées) en type de destination. Si la conversion échoue pour un paramètre d’entrée, MSBuild émet une erreur et n’appelle pas la méthode Execute() de la tâche.

Exemple 1

Description

La classe C# suivante montre une tâche qui dérive de la classe d’assistance Task. Cette tâche retourne true, ce qui indique qu’elle a réussi.

Code

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

Exemple 2

Description

La classe C# suivante montre une tâche qui implémente l’interface ITask. Cette tâche retourne true, ce qui indique qu’elle a réussi.

Code

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

Exemple 3

Description

La classe C# montre une tâche qui dérive de la classe d’assistance Task. Elle comprend une propriété de type chaîne obligatoire, et déclenche un événement qui est affiché par tous les journaux inscrits.

Code

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

Exemple 4

Description

L’exemple suivant montre un fichier projet qui appelle l’exemple de tâche précédent (SimpleTask3).

Code

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