Freigeben über


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 Executehinzufü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 truezurü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 truezurü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 truezurü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>