Schreiben von Aufgaben
Aufgaben stellen den Code bereit, der während des Buildvorgangs ausgeführt wird. Aufgaben sind in Zielen enthalten. Eine Bibliothek mit typischen Aufgaben ist in MSBuild enthalten, und Sie können auch eigene Aufgaben erstellen. Weitere Informationen zur Bibliothek von Aufgaben, die in MSBuild enthalten sind, finden Sie unter Aufgabenreferenz.
Aufgaben
Beispiele für Aufgaben sind Copy, die eine oder mehrere Dateien kopiert, MakeDir, die ein Verzeichnis erstellt, und Csc, die C#-Quellcodedateien kompiliert. Jede Aufgabe wird als .NET-Klasse implementiert, die die ITask Schnittstelle implementiert, die in der Microsoft.Build.Framework.dll assembly definiert ist.
Es gibt zwei Ansätze, die Sie bei der Implementierung einer Aufgabe verwenden können:
Implementieren Sie die ITask Schnittstelle direkt.
Leiten Sie Ihre Klasse von der Hilfsklasse Task ab, die in der Assembly Microsoft.Build.Utilities.dll definiert ist. Die Aufgabe implementiert ITask und stellt Standardimplementierungen einiger ITask-Elemente bereit. Darüber hinaus ist die Protokollierung einfacher.
In beiden Fällen müssen Sie ihrer Klasse eine Methode mit dem Namen Execute
hinzufügen. Dies ist die Methode, die aufgerufen wird, wenn die Aufgabe ausgeführt wird. Diese Methode akzeptiert keine Parameter und gibt einen Boolean
Wert zurück: true
, wenn die Aufgabe erfolgreich war oder false
, wenn sie fehlgeschlagen ist. Das folgende Beispiel zeigt eine Aufgabe, die keine Aktion ausführt und erfolgreich abgeschlossen wird (gibt true
zurück).
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace MyTasks
{
public class SimpleTask : Task
{
public override bool Execute()
{
return true;
}
}
}
Die folgende Projektdatei führt diesen Vorgang aus:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MyTarget">
<SimpleTask />
</Target>
</Project>
Wenn Vorgänge ausgeführt werden, können sie auch Eingaben aus der Projektdatei empfangen, wenn Sie .NET-Eigenschaften für die Aufgabenklasse erstellen. MSBuild legt diese Eigenschaften unmittelbar vor dem Aufrufen der Execute
-Methode der Aufgabe fest. Verwenden Sie z.B. wie im Folgenden dargestellten Aufgabencode, um eine Zeichenfolgeneigenschaft zu erstellen:
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; }
}
}
Die folgende Projektdatei führt diesen Vorgang aus und legt MyProperty
auf den angegebenen Wert fest:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MyTarget">
<SimpleTask MyProperty="Value for MyProperty" />
</Target>
</Project>
Registrieren von Aufgaben
Wenn ein Projekt einen Vorgang ausführt, muss MSBuild wissen, wie die Assembly gefunden und ausgeführt wird, die die Taskklasse enthält. Aufgaben werden mithilfe des UsingTask-Elements (MSBuild)registriert.
Wenn Ihre Aufgabe laufzeitspezifische Abhängigkeiten hat, müssen Sie MSBuild mitteilen, dass die Aufgabe in einer bestimmten Umgebung ausgeführt werden soll, indem Sie die Architecture
und/oder Runtime
in seiner UsingTask angeben.
Die MSBuild-Datei Microsoft.Common.tasks ist eine Projektdatei, die eine Liste der UsingTask
Elemente enthält, die alle Aufgaben registrieren, die mit MSBuildbereitgestellt werden. Diese Datei wird beim Erstellen eines Projekts automatisch eingeschlossen. Wenn ein Vorgang, der in Microsoft.Common.tasks registriert ist, auch in der aktuellen Projektdatei registriert ist, hat die aktuelle Projektdatei Vorrang, sodass Sie einen Standardvorgang mit Ihrem eigenen Vorgang außer Kraft setzen können, der denselben Namen hat.
Tipp
Sie können eine Liste der Aufgaben anzeigen, die mit einer bestimmten Version von MSBuild bereitgestellt werden, indem Sie den Inhalt der Microsoft.Common.tasksanzeigen.
Auslösen von Ereignissen aus einer Aufgabe
Wenn Ihre Aufgabe von der Task Hilfsklasse abgeleitet ist, können Sie eine der folgenden Hilfsmethoden für die Task Klasse verwenden, um Ereignisse auszuheben, die von allen registrierten Protokollierern abgefangen und angezeigt werden:
public override bool Execute()
{
Log.LogError("messageResource1", "1", "2", "3");
Log.LogWarning("messageResource2");
Log.LogMessage(MessageImportance.High, "messageResource3");
...
}
Wenn Ihre Aufgabe ITask direkt implementiert, können Sie diese Ereignisse dennoch auslösen, aber Sie müssen die IBuildEngine-Schnittstelle verwenden. Das folgende Beispiel zeigt eine Aufgabe, die ITask implementiert und ein benutzerdefiniertes Ereignis auslöst:
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;
}
}
Erfordern, dass Aufgabenparameter festgelegt werden
Sie können bestimmte Vorgangseigenschaften als "erforderlich" markieren, damit jede Projektdatei, die den Vorgang ausführt, Werte für diese Eigenschaften festlegen muss oder der Build fehlschlägt. Wenden Sie das attribut [Required]
auf die .NET-Eigenschaft in Ihrer Aufgabe wie folgt an:
[Required]
public string RequiredProperty { get; set; }
Das [Required]
-Attribut wird durch RequiredAttribute im Microsoft.Build.Framework-Namespace definiert.
So ruft MSBuild eine Aufgabe auf
Beim Aufrufen eines Vorgangs instanziiert MSBuild zunächst die Vorgangsklasse und ruft dann die Eigenschaftensatzer dieses Objekts für Vorgangsparameter auf, die im Aufgabenelement in der Projektdatei festgelegt sind. Wenn das Aufgabenelement keinen Parameter angibt oder der im Element angegebene Ausdruck als leere Zeichenfolge ausgewertet wird, wird der Eigenschaftensatzer nicht aufgerufen.
Beispiel: im Projekt
<Project>
<Target Name="InvokeCustomTask">
<CustomTask Input1=""
Input2="$(PropertyThatIsNotDefined)"
Input3="value3" />
</Target>
</Project>
Hier wird nur der Setter für Input3
aufgerufen.
Ein Vorgang sollte nicht von einer relativen Reihenfolge des Aufrufs von Parameter-Property-Setter abhängen.
Aufgabenparametertypen
MsBuild behandelt systemeigene Eigenschaften vom Typ string
, bool
, ITaskItem
und ITaskItem[]
. Wenn eine Aufgabe einen Parameter eines anderen Typs akzeptiert, ruft MSBuild ChangeType zum Konvertieren von string
(mit erweiterten Eigenschafts- und Elementverweisen) in den Zieltyp auf. Wenn die Konvertierung für einen Eingabeparameter fehlschlägt, gibt MSBuild einen Fehler aus und ruft die Execute()
-Methode der Aufgabe nicht auf.
Packen der Aufgabe
Die empfohlene Methode zum Verteilen einer Aufgabe befindet sich in einem NuGet-Paket. Das Paket muss alle Abhängigkeiten bündeln. Dieses Thema wird in einem Lernprogramm ausführlich erläutert, das Sie durch das Erstellen einer benutzerdefinierten Aufgabe führt. Siehe Erstellen eines NuGet-Pakets.
Beispiel 1
Beschreibung
Diese folgende C#-Klasse veranschaulicht eine Aufgabe, die von der Task Hilfsklasse abgeleitet wird. Dieser Vorgang gibt true
zurück, was anzeigt, dass er erfolgreich war.
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;
}
}
}
Beispiel 2
Beschreibung
Diese folgende C#-Klasse veranschaulicht eine Aufgabe, die die ITask Schnittstelle implementiert. Diese Aufgabe gibt true
zurück, was anzeigt, dass sie erfolgreich war.
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;
}
}
}
Beispiel 3
Beschreibung
Diese C#-Klasse veranschaulicht eine Aufgabe, die von der Task Hilfsklasse abgeleitet wird. Sie verfügt über eine erforderliche Zeichenfolgeneigenschaft und löst ein Ereignis aus, das von allen registrierten Loggern angezeigt wird.
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;
}
}
}
Beispiel 4
Beschreibung
Das folgende Beispiel zeigt eine Projektdatei, die die vorherige Aufgabenstellung, SimpleTask3, aufruft.
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>