Diagnostizieren von MSBuild-Vorgangsfehlern

MSB6006 wird in folgendem Fall ausgegeben: Eine aus ToolTask abgeleitete Klasse führt einen Toolprozess aus, der einen Exitcode ungleich null ausgibt, wenn der Task keinen spezifischeren Fehler protokolliert hat.

Ermitteln des fehlerhaften Vorgangs

Bei einem Taskfehler muss zuerst herausgefunden werden, in welchem Task der Fehler auftritt.

Der Fehlertext gibt den Namen des Tools (entweder ein von der ToolName-Implementierung des Tasks bereitgestellter Anzeigename oder der Name der ausführbaren Datei) und den numerischen Exitcode an. In error MSB6006: "custom tool" exited with code 1. lautet der Toolname z. B. custom tool und der Exitcode 1.

So suchen Sie den fehlerhaften MSBuild-Vorgang

  • In Befehlszeilenbuilds: Wenn der Build so konfiguriert ist, dass eine Zusammenfassung enthalten ist (Standardeinstellung), sieht die Zusammenfassung wie folgt aus:

    Build FAILED.
    
    "S:\MSB6006_demo\MSB6006_demo.csproj" (default target) (1) ->
    (InvokeToolTask target) ->
      S:\MSB6006_demo\MSB6006_demo.csproj(19,5): error MSB6006: "custom tool" exited with code 1.
    

    Dieses Ergebnis weist darauf hin, dass der Fehler in einem Task aufgetreten ist, der in Zeile 19 der Datei S:\MSB6006_demo\MSB6006_demo.csproj in einem Ziel namens InvokeToolTask im Projekt S:\MSB6006_demo\MSB6006_demo.csproj definiert wurde.

  • Auf der Visual Studio-Benutzeroberfläche: Die gleichen Informationen stehen in der Visual Studio-Fehlerliste in den Spalten Project, File und Line zur Verfügung.

Suchen nach weiteren Fehlerinformationen

Fehler MSB6006 wird ausgegeben, wenn der Task keinen spezifischen Fehler protokolliert hat. Der Grund hierfür ist häufig, dass der Task das von dem aufgerufenen Tool ausgegebene Fehlerformat nicht kennt.

Ordnungsgemäß konfigurierte Tools geben im Allgemeinen Kontext- oder Fehlerinformationen in ihren standardmäßigen Ausgabe- oder Fehlerstream aus, und Tasks erfassen und protokollieren diese Informationen in der Regel. Sehen Sie sich die Protokolleinträge vor dem Auftreten des Fehlers an, um weitere Informationen zu erhalten. Möglicherweise muss der Build mit einem höheren Protokolliergrad erneut ausgeführt werden, um diese Informationen beizubehalten. Der zusätzliche Kontext oder weitere Fehlerinformationen in den Protokollen sollten auf die Ursache eines Problems hinweisen. Andernfalls müssen Sie die möglichen Ursachen eingrenzen, indem Sie die Eigenschaften und Elemente untersuchen, die als Eingaben für den fehlerhaften Vorgang verwendet wurden.

Hinweis

MSBuild erkennt ein bestimmtes Diagnoseausgabeformat. Die Details dieses Formats sind in MSBuild- und Visual Studio-Format für Diagnosenachrichten dokumentiert.

Debuggen eines Tasks

Nachfolgend sind einige allgemeine Tipps zum Debuggen von MSBuild-Aufgaben aufgeführt.

  • Schränken Sie den Umfang des Repro-Falls so weit wie möglich ein (z. B. legen Sie /p:BuildProjectReferences=false fest und starten Sie MSBuild mit einem bestimmten Projekt oder einem bestimmten Ziel), um mit weniger Code arbeiten zu müssen.
  • Verwenden Sie die MSBuild-Befehlszeilenoption /m:1, um einen einzelnen MSBuild-Prozess debuggen zu müssen.
  • Legen Sie die Umgebungsvariable MSBUILDDEBUGONSTART auf 1 fest, um beim Start einen Debugger an MSBuild anzufügen.
  • Legen Sie einen Haltepunkt bei der Execute-Methode des Tasks fest, der durchlaufen werden soll.

Debuggen eines benutzerdefinierten Tasks

Wenn Sie Code für einen benutzerdefinierten Task schreiben, können Sie das Debuggen vereinfachen, indem Sie einen Aufruf hinzufügen, um den Debugger in der Execute-Methode des Tasks aufzurufen. Sie können diesen Code mit einer Überprüfung der Umgebungsvariablen eingrenzen, damit, wenn ein*e Benutzer*in diese Umgebungsvariable festlegt, der Task abgebrochen wird und ihm/ihr die Möglichkeit gibt, zu debuggen. Sie können System.Diagnostics.Debugger.Launch oder System.Diagnostics.Debugger.Break verwenden, um den Debugger zu starten oder zu unterbrechen.

Vergewissern Sie sich, dass Sie einem benutzerdefinierten Task so viel Protokollierung wie möglich hinzufügen, damit Benutzer*innen den Task möglichst leicht debuggen können. Das ist wichtig, wenn Sie schlussendlich die Grundursache eines Fehlers ermitteln; fügen Sie ausreichend Protokollierungscode hinzu, um diesen Fehlermodus in Zukunft zu identifizieren und zu melden.

Ziehen Sie in Erwägung, mithilfe von xUnit eine Testumgebung für einen Task einzurichten. Lesen Sie Komponententests für C# in .NET Core mit „dotnet test“ und xUnit Sie können den xUnit-Test so konfigurieren, dass die MSBuild-API MSBuild programmgesteuert mit einer Pseudoprojektdatei aufruft, die die Eigenschaften, Elemente und Ziele enthält, die Sie für die Ausführung des betreffenden Tasks benötigen. In einigen Fällen kann es sinnvoll sein, ein Pseudobuildmodul zu erstellen. Unter Komponententest für einen benutzerdefinierten MSBuild-Task mit Visual Studio können Sie sich ein Beispiel hierzu ansehen.

In .NET SDK-Projekten können Sie auch launchSettings.json ändern, um ein spezielles Debuggen-Profil hinzuzufügen, das MSBuild.exe mit den Befehlszeilenargumenten und den Umgebungsvarianten ausführt, die weiter oben in diesem Artikel erwähnt wurden.

"profiles": {
  "Debug Build": {
    "commandName": "Executable",
    "executablePath": "$(MSBuildBinPath)\\MSBuild.exe",
    "commandLineArgs": "/p:Configuration=$(Configuration) $(ProjectFileName) /m:1",
    "workingDirectory": "$(ProjectDir)"
  }
}

Wenn Sie dazu aufgefordert werden wollen, Ihren eigenen Debugger zur Laufzeit anzufügen, legen Sie die Umgebungsvariable MSBUILDDEBUGONSTART auf 2 fest. Dies kann hilfreich sein, wenn Sie einen anderen Debugger verwenden, z. B. unter macOS, sollte Visual Studio nicht verfügbar sein.