Écriture de tâches
Les tâches fournissent le code qui s’exécute pendant le processus de génération. Les tâches sont contenues dans les cibles. Une bibliothèque de tâches classiques est incluse dans MSBuild, et vous pouvez également créer vos propres tâches. Pour plus d’informations sur la bibliothèque de tâches incluses dans MSBuild, consultez référence de tâche.
Tâches
Parmi les exemples de tâches, citons Copier, qui copie un ou plusieurs fichiers, MakeDir, qui crée un répertoire et Csc, qui compile les fichiers de code source C#. Chaque tâche est implémentée en tant que classe .NET qui implémente l’interface ITask, qui est définie dans l’assembly Microsoft.Build.Framework.dll.
Il existe deux approches que vous pouvez utiliser lors de l’implémentation d’une tâche :
Implémentez directement l’interface ITask.
Dérivez votre classe de la classe d’assistance Task, qui est 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. En outre, 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 lors de l’exécution de la tâche. Cette méthode ne prend 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 correctement (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 s’exécutent, elles peuvent également recevoir des entrées du fichier projet si vous créez des propriétés .NET sur la classe de tâches. MSBuild définit ces propriétés immédiatement avant d’appeler la méthode Execute
de la tâche. Pour créer une propriété de chaîne, utilisez le code de tâche tel que :
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âches. 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 automatiquement inclus 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, le fichier projet actuel est prioritaire. Vous pouvez donc remplacer une tâche par défaut par votre propre tâche portant le même nom.
Conseil
Vous pouvez voir une liste des tâches fournies avec une version spécifique de MSBuild en affichant le contenu de ses 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 sur la classe Task pour déclencher des événements qui seront interceptés et affichés par les enregistreurs d’événements 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 toujours déclencher de tels événements, mais vous devez 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 que les paramètres de tâche soient définis
Vous pouvez marquer certaines propriétés de tâche comme « obligatoires » afin que tout fichier projet qui exécute la tâche doit définir des valeurs pour ces propriétés ou que la build échoue. Appliquez l’attribut [Required]
à la propriété .NET dans votre tâche comme suit :
[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, le jeu 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 type différent, MSBuild appelle ChangeType pour effectuer une conversion 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.
Empaquetage de la tâche
La méthode recommandée pour distribuer une tâche se trouve dans un package NuGet. Le package doit regrouper toutes les dépendances. Cette rubrique est expliquée minutieusement dans un didacticiel qui vous guide tout au long de la création d’une tâche personnalisée. Consultez Créer un package NuGet.
Exemple 1
Description
Cette classe C# suivante illustre une tâche dérivant de la classe d’assistance Task. Cette tâche retourne true
, indiquant 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
Cette classe C# suivante illustre une tâche implémentant l’interface ITask. Cette tâche retourne true
, indiquant 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
Cette classe C# illustre une tâche qui dérive de la classe d’assistance Task. Il a une propriété de chaîne de caractères requise et déclenche un événement affiché par tous les enregistreurs 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 appelant 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>