Vorgehensweise: Erweitern des Visual Studio-BuildprozessesHow to: Extend the Visual Studio build process

Der Visual Studio-Buildprozess wird durch eine Reihe von MSBuild-TARGETS-Dateien definiert, die in die Projektdatei importiert werden.The Visual Studio build process is defined by a series of MSBuild .targets files that are imported into your project file. Eine dieser importierten Dateien (Microsoft.Common.targets) kann erweitert werden, um Ihnen das Ausführen benutzerdefinierter Aufgaben in unterschiedlichen Phasen während des Buildprozesses zu ermöglichen.One of these imported files, Microsoft.Common.targets, can be extended to allow you to run custom tasks at several points in the build process. In diesem Artikel werden die zwei Methoden erläutert, mit denen der Visual Studio-Buildprozess erweitert werden kann:This article explains two methods you can use to extend the Visual Studio build process:

  • Überschreiben spezifischer vordefinierter Ziele, die in den allgemeinen Zielen definiert werden (Microsoft.Common.targets oder die importierten Dateien)Overriding specific predefined targets defined in the common targets (Microsoft.Common.targets or the files that it imports).

  • Überschreiben der DependsOn-Eigenschaften, die in den allgemeinen Zielen definiert werdenOverriding the "DependsOn" properties defined in the common targets.

Überschreiben vordefinierter ZieleOverride predefined targets

Die allgemeinen Ziele enthalten vordefinierte, leere Ziele, die vor und nach einigen der wichtigen Ziele im Buildprozess aufgerufen werden.The common targets contains a set of predefined empty targets that is called before and after some of the major targets in the build process. Beispielsweise ruft MSBuild das BeforeBuild-Ziel vor dem CoreBuild-Hauptziel und das AfterBuild-Ziel nach dem CoreBuild-Ziel auf.For example, MSBuild calls the BeforeBuild target before the main CoreBuild target and the AfterBuild target after the CoreBuild target. Die leeren Ziele in den allgemeinen Zielen führen standardmäßig keine Aktionen aus. Sie können aber ihr Standardverhalten überschreiben, indem Sie die Ziele definieren, die in einer Projektdatei enthalten sein sollen, die allgemeine Ziele importiert.By default, the empty targets in the common targets do nothing, but you can override their default behavior by defining the targets you want in a project file that imports the common targets. Durch das Überschreiben der vordefinierten Ziele können Sie den Buildprozess mit MSBuild-Aufgaben besser steuern.By overriding the predefined targets, you can use MSBuild tasks to give you more control over the build process.

Hinweis

Projekte im Format von SDKs importieren Ziele implizit nach der letzten Codezeile der Projektdatei.SDK-style projects have an implicit import of targets after the last line of the project file. Das heißt, Sie können die Standardziele nicht überschreiben, es sei denn, Sie legen Ihre Importe wie unter Vorgehensweise: Verwenden von SDKs für MSBuild-Projekte beschrieben manuell fest.This means that you cannot override default targets unless you specify your imports manually as described in How to: Use MSBuild project SDKs.

So überschreiben Sie ein vordefiniertes ZielTo override a predefined target

  1. Identifizieren Sie ein vordefiniertes Ziel in den allgemeinen Zielen, das Sie überschreiben möchten.Identify a predefined target in the common targets that you want to override. In der Tabelle unten finden Sie die vollständige Liste der Ziele, die Sie bedenkenlos überschreiben können.See the table below for the complete list of targets that you can safely override.

  2. Definieren Sie das Ziel bzw. die Ziele am Ende der Projektdatei, unmittelbar vor dem </Project>-Tag.Define the target or targets at the end of your project file, immediately before the </Project> tag. Beispiel:For example:

    <Project>
        ...
        <Target Name="BeforeBuild">
            <!-- Insert tasks to run before build here -->
        </Target>
        <Target Name="AfterBuild">
            <!-- Insert tasks to run after build here -->
        </Target>
    </Project>
    
  3. Erstellen Sie die Projektdatei.Build the project file.

In der folgenden Tabelle werden alle Ziele in den allgemeinen Zielen aufgeführt, die Sie bedenkenlos überschreiben können.The following table shows all of the targets in the common targets that you can safely override.

ZielnameTarget name BESCHREIBUNGDescription
BeforeCompile, AfterCompileBeforeCompile, AfterCompile Aufgaben, die in eines dieser Ziele eingefügt wurden, werden vor oder nach Abschluss der Kompilierung ausgeführt.Tasks that are inserted in one of these targets run before or after core compilation is done. Die meisten Anpassungen werden in einem dieser beiden Ziele ausgeführt.Most customizations are done in one of these two targets.
BeforeBuild, AfterBuildBeforeBuild, AfterBuild Aufgaben, die in eines dieser Ziele eingefügt wurden, werden ausgeführt, bevor oder nachdem alles Weitere erstellt wurde.Tasks that are inserted in one of these targets will run before or after everything else in the build. Hinweis: Die Ziele BeforeBuild und AfterBuild wurden bereits in Kommentaren am Ende der meisten Projektdateien definiert. Dadurch können Sie ohne großen Aufwand Pre- und Postbuildereignisse zu Ihrer Projektdatei hinzufügen.Note: The BeforeBuild and AfterBuild targets are already defined in comments at the end of most project files, allowing you to easily add pre- and post-build events to your project file.
BeforeRebuild, AfterRebuildBeforeRebuild, AfterRebuild Aufgaben, die in eines dieser Ziele eingefügt wurden, werden ausgeführt, bevor oder nachdem die Funktion zum Neuerstellen von Kernen aufgerufen wurde.Tasks that are inserted in one of these targets run before or after the core rebuild functionality is invoked. Die Reihenfolge der Ausführung der Ziele in Microsoft.Common.targets lautet wie folgt: BeforeRebuild, Clean, Build und anschließend AfterRebuild.The order of target execution in Microsoft.Common.targets is: BeforeRebuild, Clean, Build, and then AfterRebuild.
BeforeClean, AfterCleanBeforeClean, AfterClean Aufgaben, die in eines dieser Ziele eingefügt wurden, werden ausgeführt, bevor oder nachdem die Funktion zum Löschen von Kernen aufgerufen wurde.Tasks that are inserted in one of these targets run before or after the core clean functionality is invoked.
BeforePublish, AfterPublishBeforePublish, AfterPublish Aufgaben, die in eines dieser Ziele eingefügt wurden, werden ausgeführt, bevor oder nachdem die Funktion zum Veröffentlichen von Kernen aufgerufen wurde.Tasks that are inserted in one of these targets run before or after the core publish functionality is invoked.
BeforeResolveReferences, AfterResolveReferencesBeforeResolveReferences, AfterResolveReferences Aufgaben, die in eines dieser Ziele eingefügt wurden, werden ausgeführt, bevor oder nachdem die Assemblyverweise aufgelöst wurden.Tasks that are inserted in one of these targets run before or after assembly references are resolved.
BeforeResGen, AfterResGenBeforeResGen, AfterResGen Aufgaben, die in eines dieser Ziele eingefügt wurden, werden ausgeführt, bevor oder nachdem Ressourcen generiert wurden.Tasks that are inserted in one of these targets run before or after resources are generated.

Beispiel: „AfterTargets“ und „BeforeTargets“Example: AfterTargets and BeforeTargets

Im folgenden Beispiel sehen Sie, wie Sie mit dem AfterTargets-Attribut ein benutzerdefiniertes Ziel hinzufügen, das eine Aktion für die Ausgabedateien ausführt.The following example shows how to use the AfterTargets attribute to add a custom target that does something with the output files. In diesem Beispiel werden die Ausgabedateien in den neuen Ordner CustomOutput kopiert.In this case, it copies the output files to a new folder CustomOutput. Im Beispiel wird auch veranschaulicht, wie die vom benutzerdefinierten Buildvorgang mit einem CustomClean-Ziel erstellten Dateien bereinigt werden, indem das BeforeTargets-Attribut verwendet und angegeben wird, dass der benutzerdefinierte Bereinigungsvorgang vor dem CoreClean-Ziel ausgeführt wird.The example also shows how to clean up the files created by the custom build operation with a CustomClean target by using a BeforeTargets attribute and specifying that the custom clean operation runs before the CoreClean target.

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
   <TargetFramework>netcoreapp3.1</TargetFramework>
   <_OutputCopyLocation>$(OutputPath)..\..\CustomOutput\</_OutputCopyLocation>
</PropertyGroup>

<Target Name="CustomAfterBuild" AfterTargets="Build">
  <ItemGroup>
    <_FilesToCopy Include="$(OutputPath)**\*"/>
  </ItemGroup>
  <Message Text="_FilesToCopy: @(_FilesToCopy)" Importance="high"/>

  <Message Text="DestFiles:
      @(_FilesToCopy->'$(_OutputCopyLocation)%(RecursiveDir)%(Filename)%(Extension)')"/>

  <Copy SourceFiles="@(_FilesToCopy)"
        DestinationFiles=
        "@(_FilesToCopy->'$(_OutputCopyLocation)%(RecursiveDir)%(Filename)%(Extension)')"/>
  </Target>

  <Target Name="CustomClean" BeforeTargets="CoreClean">
    <Message Text="Inside Custom Clean" Importance="high"/>
    <ItemGroup>
      <_CustomFilesToDelete Include="$(_OutputCopyLocation)**\*"/>
    </ItemGroup>
    <Delete Files='@(_CustomFilesToDelete)'/>
  </Target>
</Project>

Warnung

Verwenden Sie dabei unbedingt andere Namen als die in der Tabelle des vorherigen Abschnitts aufgelisteten vordefinierten Ziele (das benutzerdefinierte Buildziel wurde hier beispielsweise CustomAfterBuild und nicht AfterBuild genannt). Das liegt daran, dass die vordefinierten Ziele vom SDK-Import überschrieben werden, der sie auch definiert.Be sure to use different names than the predefined targets listed in the table in the previous section (for example, we named the custom build target here CustomAfterBuild, not AfterBuild), since those predefined targets are overridden by the SDK import which also defines them. Der Import der Zieldatei, die diese Ziele überschreibt, wird nicht angezeigt. Die Datei wird jedoch implizit am Ende der Projektdatei hinzugefügt, wenn Sie die Methode des Sdk-Attributs zum Verweisen auf ein SDK verwenden.You don't see the import of the target file that overrides those targets, but it is implicitly added to the end of the project file when you use the Sdk attribute method of referencing an SDK.

Überschreiben von DependsOn-EigenschaftenOverride DependsOn properties

Mit dem Überschreiben von vordefinierten Zielen lässt sich der Buildprozess leicht erweitern. Da MSBuild die Definition von Zielen aber nacheinander auswertet, können Sie ein anderes Projekt, das Ihr Projekt importiert, nicht daran hindern, die bereits überschriebenen Ziele noch einmal zu überschreiben.Overriding predefined targets is an easy way to extend the build process, but, because MSBuild evaluates the definition of targets sequentially, there is no way to prevent another project that imports your project from overriding the targets you already have overridden. Das letzte in der Projektdatei definierte AfterBuild-Ziel wird z.B. während des Buildprozesses verwendet, nachdem alle anderen Projekte importiert wurden.So, for example, the last AfterBuild target defined in the project file, after all other projects have been imported, will be the one that is used during the build.

Sie können sich vor dem unbeabsichtigten Überschreiben von Zielen schützen, indem Sie die DependsOn-Eigenschaften überschreiben, die in den DependsOnTargets-Attributen der allgemeinen Ziele verwendet werden.You can guard against unintended overrides of targets by overriding the DependsOn properties that are used in DependsOnTargets attributes throughout the common targets. So enthält das Build-Ziel z.B. einen DependsOnTargets-Attributwert von "$(BuildDependsOn)".For example, the Build target contains a DependsOnTargets attribute value of "$(BuildDependsOn)". Zu berücksichtigen:Consider:

<Target Name="Build" DependsOnTargets="$(BuildDependsOn)"/>

Dieser XML-Codeausschnitt gibt an, dass vor der Ausführung des Build-Ziels alle in der BuildDependsOn-Eigenschaft angegebenen Ziele zuerst ausgeführt werden müssen.This piece of XML indicates that before the Build target can run, all the targets specified in the BuildDependsOn property must run first. Die BuildDependsOn-Eigenschaft ist definiert als:The BuildDependsOn property is defined as:

<PropertyGroup>
    <BuildDependsOn>
        BeforeBuild;
        CoreBuild;
        AfterBuild
    </BuildDependsOn>
</PropertyGroup>

Sie können diesen Eigenschaftswert überschreiben, indem Sie eine andere Eigenschaft mit dem Namen BuildDependsOn am Ende der Projektdatei deklarieren.You can override this property value by declaring another property named BuildDependsOn at the end of your project file. Durch Einschließen der vorherigen BuildDependsOn-Eigenschaft in die neue Eigenschaft können Sie neue Ziele am Anfang und Ende der Zielliste hinzufügen.By including the previous BuildDependsOn property in the new property, you can add new targets to the beginning and end of the target list. Beispiel:For example:

<PropertyGroup>
    <BuildDependsOn>
        MyCustomTarget1;
        $(BuildDependsOn);
        MyCustomTarget2
    </BuildDependsOn>
</PropertyGroup>

<Target Name="MyCustomTarget1">
    <Message Text="Running MyCustomTarget1..."/>
</Target>
<Target Name="MyCustomTarget2">
    <Message Text="Running MyCustomTarget2..."/>
</Target>

Projekte, in die Ihre Projektdateien importiert werden, können diese Eigenschaften überschreiben, ohne die von Ihnen vorgenommenen Anpassungen zu überschreiben.Projects that import your project files can override these properties without overwriting the customizations that you have made.

So überschreiben Sie eine DependsOn-EigenschaftTo override a DependsOn property

  1. Identifizieren Sie eine vordefinierte DependsOn-Eigenschaft in den allgemeinen Zielen, die Sie überschreiben möchten.Identify a predefined DependsOn property in the common targets that you want to override. In der folgenden Tabelle finden Sie eine Liste der Eigenschaften der häufig überschriebenen DependsOn-Eigenschaften.See the table below for a list of the commonly overridden DependsOn properties.

  2. Definieren Sie eine andere Instanz der Eigenschaft oder Eigenschaften am Ende der Projektdatei.Define another instance of the property or properties at the end of your project file. Schließen Sie die ursprüngliche Eigenschaft, z.B. $(BuildDependsOn), in die neue Eigenschaft ein.Include the original property, for example $(BuildDependsOn), in the new property.

  3. Definieren Sie Ihre benutzerdefinierten Ziele vor oder nach der Eigenschaftsdefinition.Define your custom targets before or after the property definition.

  4. Erstellen Sie die Projektdatei.Build the project file.

Häufig überschriebene DependsOn-EigenschaftenCommonly overridden DependsOn properties

EigenschaftennameProperty name BESCHREIBUNGDescription
BuildDependsOn Die zu überschreibende Eigenschaft, wenn Sie benutzerdefinierte Ziele vor oder nach dem gesamten Buildprozess einfügen möchtenThe property to override if you want to insert custom targets before or after the entire build process.
CleanDependsOn Die zu überschreibende Eigenschaft, wenn Sie die Ausgabe Ihres benutzerdefinierten Buildprozesses bereinigen möchtenThe property to override if you want to clean up output from your custom build process.
CompileDependsOn Die zu überschreibende Eigenschaft, wenn Sie benutzerdefinierte Prozesse vor oder nach dem Kompilieren einfügen möchtenThe property to override if you want to insert custom processes before or after the compilation step.

Beispiel: „BuildDependsOn“ und „CleanDependsOn“Example: BuildDependsOn and CleanDependsOn

Das folgende Beispiel ähnelt in vielerlei Hinsicht dem Beispiel BeforeTargets und AfterTargets, zeigt jedoch, wie eine ähnliche Funktionalität erzielt werden kann.The following example is similar to the BeforeTargets and AfterTargets example, but shows how to achieve similar functionality. Es wird der Build erweitert, indem mithilfe von BuildDependsOn Ihre eigene CustomAfterBuild-Aufgabe hinzugefügt wird, die die Ausgabedateien nach dem Buildvorgang kopiert. Zudem wird mithilfe von CleanDependsOn die entsprechende CustomClean-Aufgabe hinzugefügt.It extends the build by using BuildDependsOn to add your own task CustomAfterBuild that copies the output files after the build, and also adds the corresponding CustomClean task by using CleanDependsOn.

In diesem Beispiel handelt es sich um ein Projekt im SDK-Format.In this example, this is an SDK-style project. Wie bereits weiter oben in diesem Artikel im Hinweis zu Projekten im SDK-Format erwähnt, müssen Sie die manuelle Importmethode anstelle des Sdk-Attributs verwenden, das in Visual Studio für das Generieren von Projektdateien verwendet wird.As mentioned in the note about SDK-style projects earlier in this article, you must use the manual import method instead of the Sdk attribute that Visual Studio uses when it generates project files.

<Project>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />

<PropertyGroup>
   <TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />

<PropertyGroup>
   <BuildDependsOn>
      $(BuildDependsOn);CustomAfterBuild
    </BuildDependsOn>

    <CleanDependsOn>
      $(CleanDependsOn);CustomClean
    </CleanDependsOn>

    <_OutputCopyLocation>$(OutputPath)..\..\CustomOutput\</_OutputCopyLocation>
  </PropertyGroup>

<Target Name="CustomAfterBuild">
  <ItemGroup>
    <_FilesToCopy Include="$(OutputPath)**\*"/>
  </ItemGroup>
  <Message Text="_FilesToCopy: @(_FilesToCopy)" Importance="high"/>

  <Message Text="DestFiles:
      @(_FilesToCopy->'$(_OutputCopyLocation)%(RecursiveDir)%(Filename)%(Extension)')"/>

  <Copy SourceFiles="@(_FilesToCopy)"
        DestinationFiles=
        "@(_FilesToCopy->'$(_OutputCopyLocation)%(RecursiveDir)%(Filename)%(Extension)')"/>
  </Target>

  <Target Name="CustomClean">
    <Message Text="Inside Custom Clean" Importance="high"/>
    <ItemGroup>
      <_CustomFilesToDelete Include="$(_OutputCopyLocation)**\*"/>
    </ItemGroup>
    <Delete Files='@(_CustomFilesToDelete)'/>
  </Target>
</Project>

Die Reihenfolge der Elemente spielt eine wichtige Rolle.The order of elements is important. Die Elemente BuildDependsOn und CleanDependsOn müssen nach dem Import der Standarddatei für SDK-Ziele angezeigt werden.The BuildDependsOn and CleanDependsOn elements must appear after importing the standard SDK targets file.

Weitere InformationenSee also