Taak schrijven
Taken bieden de code die wordt uitgevoerd tijdens het buildproces. Taken zijn opgenomen in doelen. Een bibliotheek met typische taken is opgenomen in MSBuild en u kunt ook uw eigen taken maken. Zie Taakreferentievoor meer informatie over de bibliotheek met taken die zijn opgenomen in MSBuild.
Taken
Voorbeelden van taken zijn Copy, waarmee een of meer bestanden worden gekopieerd, MakeDir, waarmee een map wordt gemaakt en Csc-, waarmee C#-broncodebestanden worden gecompileerd. Elke taak wordt geïmplementeerd als een .NET-klasse die de ITask-interface implementeert, die is gedefinieerd in de Microsoft.Build.Framework.dll assembly.
Er zijn twee benaderingen die u kunt gebruiken bij het implementeren van een taak:
Implementeer de ITask interface rechtstreeks.
Uw klasse afleiden van de helperklasse Task, die is gedefinieerd in de Microsoft.Build.Utilities.dll assembly. Taak implementeert ITask en biedt standaardimplementaties van sommige ITask-leden. Daarnaast is logboekregistratie eenvoudiger.
In beide gevallen moet u een methode met de naam Execute
aan uw klasse toevoegen. Dit is de methode die wordt aangeroepen wanneer de taak wordt uitgevoerd. Deze methode gebruikt geen parameters en retourneert een Boolean
waarde: true
als de taak is geslaagd of false
als deze is mislukt. In het volgende voorbeeld ziet u een taak die geen actie uitvoert en die is voltooid (retourneert true
).
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace MyTasks
{
public class SimpleTask : Task
{
public override bool Execute()
{
return true;
}
}
}
In het volgende projectbestand wordt deze taak uitgevoerd:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MyTarget">
<SimpleTask />
</Target>
</Project>
Wanneer taken worden uitgevoerd, kunnen ze ook invoer ontvangen van het projectbestand als u .NET-eigenschappen voor de taakklasse maakt. MSBuild stelt deze eigenschappen direct in voordat de Execute
methode van de taak wordt aangeroepen. Als u een tekenreekseigenschap wilt maken, gebruikt u taakcode zoals:
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; }
}
}
In het volgende projectbestand wordt deze taak uitgevoerd en wordt MyProperty
ingesteld op de opgegeven waarde:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MyTarget">
<SimpleTask MyProperty="Value for MyProperty" />
</Target>
</Project>
Taken registreren
Als een project een taak gaat uitvoeren, moet MSBuild weten hoe de assembly met de taakklasse moet worden gevonden en uitgevoerd. Taken worden geregistreerd met behulp van het UsingTask-element (MSBuild).
Als uw taak runtimespecifieke afhankelijkheden heeft, moet u MSBuild informeren dat de taak in een specifieke omgeving moet worden uitgevoerd door de Architecture
en/of Runtime
in de UsingTask-aan te geven.
Het MSBuild-bestand Microsoft.Common.tasks is een projectbestand met een lijst met UsingTask
elementen die alle taken registreren die worden geleverd bij MSBuild. Dit bestand wordt automatisch opgenomen bij het bouwen van een project. Als een taak die is geregistreerd in Microsoft.Common.tasks ook is geregistreerd in het huidige projectbestand, heeft het huidige projectbestand voorrang, zodat u een standaardtaak kunt overschrijven met uw eigen taak met dezelfde naam.
Tip
U ziet een lijst met de taken die zijn geleverd met een specifieke versie van MSBuild door de inhoud van de Microsoft.Common.taskste bekijken.
Gebeurtenissen uit een taak genereren
Als uw taak is afgeleid van de Task helperklasse, kunt u een van de volgende helpermethoden in de Task-klasse gebruiken om gebeurtenissen te genereren die worden gevangen en weergegeven door geregistreerde logboekregistraties:
public override bool Execute()
{
Log.LogError("messageResource1", "1", "2", "3");
Log.LogWarning("messageResource2");
Log.LogMessage(MessageImportance.High, "messageResource3");
...
}
Als uw taak ITask rechtstreeks implementeert, kunt u dergelijke gebeurtenissen nog steeds genereren, maar moet u de IBuildEngine-interface gebruiken. In het volgende voorbeeld ziet u een taak waarmee ITask wordt geïmplementeerd en een aangepaste gebeurtenis wordt gegenereerd:
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;
}
}
Vereisen dat taakparameters worden ingesteld
U kunt bepaalde taakeigenschappen als 'vereist' markeren, zodat elk projectbestand dat de taak uitvoert waarden moet instellen voor deze eigenschappen of dat de build mislukt. Pas het kenmerk [Required]
als volgt toe op de .NET-eigenschap in uw taak:
[Required]
public string RequiredProperty { get; set; }
Het kenmerk [Required]
wordt gedefinieerd door RequiredAttribute in de Microsoft.Build.Framework naamruimte.
Hoe MSBuild een taak aanroept
Wanneer u een taak aanroept, instanteert MSBuild eerst de taakklasse en roept vervolgens de eigenschapssetters van dat object aan voor taakparameters die zijn ingesteld in het taakelement in het projectbestand. Als het taakelement geen parameter opgeeft of als de expressie die is opgegeven in het element een lege tekenreeks evalueert, wordt de eigenschapssetter niet aangeroepen.
Bijvoorbeeld in het project
<Project>
<Target Name="InvokeCustomTask">
<CustomTask Input1=""
Input2="$(PropertyThatIsNotDefined)"
Input3="value3" />
</Target>
</Project>
alleen de setter voor Input3
wordt aangeroepen.
Een taak mag niet afhankelijk zijn van de relatieve volgorde van het aanroepen van eigenschapinstellingen voor parameters.
Taakparametertypen
De MSBuild verwerkt systeemeigen eigenschappen van het type string
, bool
, ITaskItem
en ITaskItem[]
. Als een taak een parameter van een ander type accepteert, roept MSBuild ChangeType aan om te converteren van string
(met alle eigenschaps- en itemverwijzingen uitgevouwen) naar het doeltype. Als de conversie mislukt voor een invoerparameter, verzendt MSBuild een fout en roept de Execute()
methode van de taak niet aan.
De taak verpakken
De aanbevolen manier om een taak te distribueren, bevindt zich in een NuGet-pakket. Het pakket moet alle afhankelijkheden bundelen. Dit onderwerp wordt uitgebreid uitgelegd in een zelfstudie waarin u wordt begeleid bij het maken van een aangepaste taak. Zie Een NuGet-pakket maken.
Voorbeeld 1
Beschrijving
In deze volgende C#-klasse ziet u een taak die is afgeleid van de Task helperklasse. Deze taak retourneert true
, waarmee wordt aangegeven dat deze is geslaagd.
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;
}
}
}
Voorbeeld 2
Beschrijving
In deze volgende C#-klasse ziet u een taak die de ITask-interface implementeert. Deze taak retourneert true
, waarmee wordt aangegeven dat deze is geslaagd.
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;
}
}
}
Voorbeeld 3
Beschrijving
Deze C#-klasse demonstreert een taak die is afgeleid van de Task helperklasse. Het heeft een vereiste tekenreekseigenschap en genereert een gebeurtenis die wordt weergegeven door alle geregistreerde logboekregistraties.
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;
}
}
}
Voorbeeld 4
Beschrijving
In het volgende voorbeeld ziet u een projectbestand dat de vorige voorbeeldtaak, SimpleTask3, aanroept.
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>