Scrittura di attività
Le attività forniscono il codice eseguito durante il processo di compilazione. Le attività sono contenute negli obiettivi. Una libreria di attività tipiche è inclusa in MSBuild ed è anche possibile creare attività personalizzate. Per altre informazioni sulla libreria di attività incluse in MSBuild, vedere Riferimento all'attività.
Attività
Esempi di attività includono Copia, che copia uno o più file, MakeDir, che crea una directory e Csc, che compila i file di codice sorgente C#. Ogni attività viene implementata come classe .NET che implementa l'interfaccia ITask, definita nell'assembly Microsoft.Build.Framework.dll.
Per implementare un'attività è possibile usare due approcci:
Implementare direttamente l'interfaccia ITask.
Deriva la tua classe dalla classe di supporto Task, definita nell'assembly Microsoft.Build.Utilities.dll. L'attività implementa ITask e fornisce implementazioni di default di alcuni membri dell'ITask. Inoltre, la registrazione dei log è più semplice.
In entrambi i casi, è necessario aggiungere alla classe un metodo denominato Execute
, ovvero il metodo chiamato quando viene eseguita l'attività. Questo metodo non accetta parametri e restituisce un valore Boolean
: true
se l'attività ha avuto esito positivo o false
se non è riuscita. Nell'esempio seguente viene illustrata un'attività che non esegue alcuna azione e viene completata correttamente (restituisce true
).
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace MyTasks
{
public class SimpleTask : Task
{
public override bool Execute()
{
return true;
}
}
}
Il file di progetto seguente esegue questa attività:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MyTarget">
<SimpleTask />
</Target>
</Project>
Quando le attività vengono eseguite, possono anche ricevere input dal file di progetto se si creano proprietà .NET nella classe di attività. MSBuild imposta queste proprietà immediatamente prima di chiamare il metodo Execute
dell'attività. Per creare una proprietà stringa, usare un codice di esempio come:
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; }
}
}
Il file di progetto seguente esegue questa attività e imposta MyProperty
sul valore specificato:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MyTarget">
<SimpleTask MyProperty="Value for MyProperty" />
</Target>
</Project>
Registrare le attività
Se un progetto eseguirà un'attività, MSBuild deve sapere come individuare ed eseguire l'assembly che contiene la classe task. Le attività vengono registrate usando l'elemento UsingTask (MSBuild).
Se l'attività presenta dipendenze specifiche del runtime, è necessario informare MSBuild che deve eseguire l'attività in un ambiente specifico indicando il Architecture
e/o il Runtime
nel relativo UsingTask.
Il file MSBuild Microsoft.Common.tasks è un file di progetto contenente un elenco di elementi UsingTask
che registrano tutte le attività fornite con MSBuild. Questo file viene incluso automaticamente durante la compilazione di un progetto. Se un'attività registrata in Microsoft.Common.tasks viene registrata anche nel file di progetto corrente, il file di progetto corrente ha la precedenza, quindi è possibile eseguire l'override di un'attività predefinita con la propria attività con lo stesso nome.
Suggerimento
È possibile visualizzare un elenco delle attività fornite con una versione specifica di MSBuild visualizzando il contenuto del relativo Microsoft.Common.tasks.
Generare eventi da un'attività
Se l'attività deriva dalla classe helper Task, è possibile usare uno dei metodi helper seguenti nella classe Task per generare eventi che verranno rilevati e visualizzati da eventuali logger registrati:
public override bool Execute()
{
Log.LogError("messageResource1", "1", "2", "3");
Log.LogWarning("messageResource2");
Log.LogMessage(MessageImportance.High, "messageResource3");
...
}
Se l'attività implementa direttamente ITask, è comunque possibile generare tali eventi, ma è necessario usare l'interfaccia IBuildEngine. L'esempio seguente mostra un'attività che implementa ITask e genera un evento personalizzato:
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;
}
}
Richiedere l'impostazione dei parametri dell'attività
È possibile contrassegnare alcune proprietà dell'attività come "obbligatorie" in modo che qualsiasi file di progetto che esegue l'attività deve impostare valori per queste proprietà o la compilazione non riesce. Applica l'attributo [Required]
alla proprietà .NET nel tuo compito come segue:
[Required]
public string RequiredProperty { get; set; }
L'attributo [Required]
viene definito da RequiredAttribute nello spazio dei nomi Microsoft.Build.Framework.
Come MSBuild richiama un'attività
Quando si richiama un'attività, MSBuild crea innanzitutto un'istanza della classe task, quindi chiama i setter di proprietà dell'oggetto per i parametri attività impostati nell'elemento task nel file di progetto. Se l'elemento task non specifica un parametro o se l'espressione specificata nell'elemento restituisce una stringa vuota, il setter della proprietà non viene chiamato.
Ad esempio, nel progetto
<Project>
<Target Name="InvokeCustomTask">
<CustomTask Input1=""
Input2="$(PropertyThatIsNotDefined)"
Input3="value3" />
</Target>
</Project>
viene chiamato solo il setter per Input3
.
Un'attività non deve dipendere da un ordine relativo di chiamata al setter della proprietà dei parametri.
Tipi di parametri dell'attività
MSBuild gestisce in modo nativo le proprietà di tipo string
, bool
, ITaskItem
e ITaskItem[]
. Se un'attività accetta un parametro di un tipo diverso, MSBuild richiama ChangeType per eseguire la conversione da string
(con tutti i riferimenti a proprietà e elementi espansi) al tipo di destinazione. Se la conversione non riesce per qualsiasi parametro di input, MSBuild genera un errore e non chiama il metodo Execute()
dell'attività.
Creazione del pacchetto dell'attività
Il modo consigliato per distribuire un'attività è in un pacchetto NuGet. Il pacchetto deve aggregare tutte le dipendenze. Questo argomento viene illustrato dettagliatamente in un'esercitazione che illustra la creazione di un'attività personalizzata. Vedere Creare un pacchetto NuGet.
Esempio 1
Descrizione
Questa classe C# seguente illustra un'attività derivata dalla classe helper Task. Questa attività restituisce true
, che indica che ha avuto esito positivo.
Codice
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;
}
}
}
Esempio 2
Descrizione
Questa classe C# seguente illustra un'attività che implementa l'interfaccia ITask. Questa attività restituisce true
, che indica che ha avuto esito positivo.
Codice
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;
}
}
}
Esempio 3
Descrizione
Questa classe C# illustra un'attività che deriva dalla classe helper Task. Ha una proprietà stringa obbligatoria e genera un evento visualizzato da tutti i logger registrati.
Codice
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;
}
}
}
Esempio 4
Descrizione
Nell'esempio seguente viene illustrato un file di progetto che richiama l'attività di esempio precedente SimpleTask3.
Codice
<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>