6. Créer ses propres tâches▲
Microsoft a déjà fourni un certain nombre de tâches permettant de réaliser les actions de base.
Et si celles-ci s'avèrent insuffisantes, vous pouvez également référencer d'autres DLLs exposant des tâches. On peut citer à ce propos « Sdc Tasks Library » (8) qui expose plus de 150 tâches différentes comme par exemple :
- Travailler avec Biztalk
- Gérer des groupes ou des utilisateurs dans Active Directory
- Gérer des packages (CAB, ZIP, WIX, MSI)
- Travailler avec des Source Control (Source Safe, Team Foundation Server, SourceGear Vault)
- Gérer IIS via la création et le paramétrage de site web dédié, de répertoires virtuels, d'Application Pool, ...
- Travailler avec des outils externes (devenv, FxCop, MsTest, NUnit, InstallShield, ...)
- Travailler avec des fichiers et des répertoires
Cependant, si malgré cette quantité de tâches différentes vous ne trouviez pas votre bonheur, Microsoft vous laisse la possibilité de créer vos propres tâches.
Et une tâche étant une simple classe .NET, cela vous laisse virtuellement la possibilité de réaliser n'importe quelle tâche d'automatisation.
6-1. Créer une tâche simple▲
La première étape pour créer une tâche est de créer une nouvelle DLL dans laquelle on référence les DLLs suivantes :
- « Microsoft.Build.Utilities » ou « Microsoft.Build.Utilities.v3.5 »
- « Microsoft.Build.Tasks » ou « Microsoft.Build.Tasks.v3.5 »
- « Microsoft.Build.Framework »
On peut ensuite créer une classe héritant de la classe « Task » et overrider la méthode « Execute ». C'est cette méthode qui sera appelée lorsque la tâche sera exécutée.
using
Microsoft.
Build.
Utilities;
namespace
CustomTasks
{
public
class
TacheSimple :
Task
{
///
<
summary
>
/// Cette méthode sera appelée lorsque la tâche sera exécutée
///
<
/summary
>
///
<
returns
>
True si la tâche réussit, sinon false
<
/returns
>
public
override
bool
Execute
(
)
{
this
.
Log.
LogMessage
(
"Message écrit par la tâche TacheSimple"
);
//La tâche a réussi
return
true
;
}
}
}
On a accès à la propriété « Log » qui permet d'afficher des messages.
Une fois cette DLL compilée, on peut référencer la tâche que l'on vient de créer et l'utiliser dans le fichier de build.
<Project
xmlns
=
"http://schemas.microsoft.com/developer/msbuild/2003"
>
<UsingTask
TaskName
=
"SimpleTask"
AssemblyFile
=
"C:\...\CustomTasks.dll"
/>
<Target
Name
=
"MainTarget"
>
<SimpleTask />
</Target>
</Project>
Microsoft (R) Build Engine Version 3.5.30729.1
[Microsoft .NET Framework, Version 2.0.50727.3053]
Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 25/02/2009 7:56:26.
Project "D:\Fichiers de build\Execute TacheSimple.proj" on node 0 (default targets).
Message écrit par la tâche TacheSimple
Done Building Project "D:\Fichiers de build\Execute TacheSimple.proj" (default targets).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.15
Notez qu'il suffit que la tâche fasse un « return false » pour qu'elle soit considérée comme échouant et donc fasse potentiellement stopper le build.
6-2. Ajouter des entrées sur sa tâche▲
6-2-1. Ajouter des entrées optionnelles▲
Il est évidemment intéressant de pouvoir paramétrer la tâche pour modifier son fonctionnement. Pour cela, il suffit d'ajouter des propriétés (obligatoires ou non) sur la classe que l'on vient de créer.
using
Microsoft.
Build.
Utilities;
namespace
CustomTasks
{
public
class
TacheSimpleAvecInput :
Task
{
private
string
nom;
public
string
Nom
{
get
{
return
nom;
}
set
{
nom =
value
;
}
}
///
<
summary
>
/// Cette méthode sera appelée lorsque la tâche sera exécutée
///
<
/summary
>
///
<
returns
>
True si la tâche a réussi, sinon false
<
/returns
>
public
override
bool
Execute
(
)
{
string
nom =
string
.
IsNullOrEmpty
(
this
.
Nom)
?
"World"
:
this
.
Nom;
this
.
Log.
LogMessage
(
"Hello "
+
nom);
return
true
;
//La tâche a réussi
}
}
}
<Project
xmlns
=
"http://schemas.microsoft.com/developer/msbuild/2003"
>
<UsingTask
TaskName
=
"TacheSimpleAvecInput"
AssemblyFile
=
"C:\...\CustomTasks.dll"
/>
<Target
Name
=
"MainTarget"
>
<TacheSimpleAvecInput />
<TacheSimpleAvecInput
Nom
=
"Pierre-Emmanuel Dautreppe"
/>
</Target>
</Project>
Microsoft (R) Build Engine Version 3.5.30729.1
[Microsoft .NET Framework, Version 2.0.50727.3053]
Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 25/02/2009 8:06:55.
Project "D:\Fichiers de build\Execute TacheSimpleAvecInput.proj" on node 0 (default targets).
Hello World
Hello Pierre-Emmanuel Dautreppe
Done Building Project "D:\Fichiers de build\Execute TacheSimpleAvecInput.proj" (default targets).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.06
6-2-2. Ajouter des entrées obligatoires▲
Pour rendre un input obligatoire, il suffit d'ajouter un attribut « Required » sur la propriété et le framework va la gérer différemment.
public
class
TacheSimpleAvecInput :
Task
{
[Required]
public
string
Nom
{
get
{
return
nom;
}
set
{
nom =
value
;
}
}
// ...Reste de l'implémentation omise
}
En exécutant de nouveau le fichier de build précédent, nous avons le résultat suivant :
Microsoft (R) Build Engine Version 3.5.30729.1
[Microsoft .NET Framework, Version 2.0.50727.3053]
Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 25/02/2009 8:13:15.
Project "D:\Fichiers de build\Execute TacheSimpleAvecInput.proj" on node 0 (default targets).
D:\Fichiers de build\Execute TacheSimpleAvecInput.proj(6,7): error MSB4044: The "TacheSimpleAvecInput" task was not given a value for the required parameter "Nom".
Done Building Project "D:\Fichiers de build\Execute TacheSimpleAvecInput.proj" (default targets) -- FAILED.
Build FAILED.
"D:\Fichiers de build\Execute TacheSimpleAvecInput.proj" (default target) (1) ->
(Target1 target) ->
D:\Fichiers de build\Execute TacheSimpleAvecInput.proj(6,7): error MSB4044: The "TacheSimpleAvecInput" task was not given a value for the required parameter "Nom".
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:00.07
6-3. Ajouter des sorties sur sa tâche▲
Une tâche peut également produire des résultats et les communiquer au build. Pour cela, il suffit d'ajouter une propriété marquée avec l'attribut « Output ».
On aura alors la possibilité dans le fichier de build d'utiliser un élément Output pour récupérer la valeur soit sous la forme de propriété, soit sous la forme d'item.
using
Microsoft.
Build.
Utilities;
using
Microsoft.
Build.
Framework;
namespace
CustomTasks
{
public
class
TacheSimpleAvecOutput :
Task
{
private
string
text;
[Output]
public
string
Text
{
get
{
return
text;
}
}
///
<
summary
>
/// Cette méthode sera appelée lorsque la tâche sera exécutée
///
<
/summary
>
///
<
returns
>
True si la tâche réussit, sinon false
<
/returns
>
public
override
bool
Execute
(
)
{
this
.
text =
"Message écrit par la tâche simple"
;
this
.
Log.
LogMessage
(
this
.
Text);
return
true
;
}
}
}
<Project
xmlns
=
"http://schemas.microsoft.com/developer/msbuild/2003"
>
<UsingTask
TaskName
=
"TacheSimpleAvecOutput"
AssemblyFile
=
"C:\...\CustomTasks.dll"
/>
<Target
Name
=
"Target1"
>
<TacheSimpleAvecOutput>
<Output
TaskParameter
=
"Text"
PropertyName
=
"OutputText"
/>
</TacheSimpleAvecOutput>
<Message
Text
=
"Tâche Message : $(OutputText)"
/>
</Target>
</Project>
Microsoft (R) Build Engine Version 3.5.30729.1
[Microsoft .NET Framework, Version 2.0.50727.3053]
Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 2/04/2009 18:23:12.
Project "D:\Fichiers de build\Execute TacheSimpleAvecOutput.proj" on node 0 (default targets).
Message écrit par la tâche simple
Tâche Message : Message écrit par la tâche simple
Done Building Project "D:\Fichiers de build\Execute TacheSimpleAvecOutput.proj" (default targets).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.03
6-4. Lever des erreurs▲
Pour faire échouer une tâche et donc potentiellement le build, il y a plusieurs possibilités au sein même de notre classe héritant de « Task » :
- Faire en sorte que la méthode « Execute » return « false »
- Lancer une exception dans la méthode « Execute »
- Utiliser les méthodes
- « LogError »,
- « LogErrorFromException »,
- « LogErrorFromResources »,
- « LogErrorWithCodeFromResources »
6-5. Debugger sa tâche▲
Il est tout à fait possible de debugger les tâches que l'on est en train de créer. Pour cela, il suffit de mettre un point d'arrêt dans la tâche et de debugger le projet avec MsBuild. Pour cela :
- Créer un fichier de build simple qui permet d'utiliser la tâche (en spécifiant dans la tâche « UsingTask » l'emplacement de la DLL compilée en debug)
- Cliquer droit sur le projet (la Class Library .NET contenant la tâche) et « Propriétés »
- Cliquer sur l'onglet « Debug »
- Sélectionner l'option « Start External Program » et choisir MsBuild (« %windir%\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe »)
- Ajouter les « Command Lines Argument » nécessaires pour lancer le fichier de projet
- Typiquement les paramètres du type « /t » ou « /p » pour lancer un target spécifique de votre fichier, ou overrider une propriété
Vous pouvez maintenant lancer votre projet en debug.