MSBuild タスク エラーを診断する

MSB6006 は、タスクによって具体的なエラーがログに記録されなかった場合に、0 以外の終了コードを返すツール プロセスを ToolTask 派生クラスが実行するときに生成されます。

失敗したタスクを特定する

タスク エラーが発生した場合は、最初の手順として、失敗しているタスクを特定します。

エラーのテキストには、ツール名 (タスクの ToolName の実装で指定されたフレンドリ名、または実行可能ファイルの名前) と、数値の終了コードが記載されています。 たとえば、error MSB6006: "custom tool" exited with code 1. では、ツール名は custom tool、終了コードは 1 です。

失敗した MSBuild タスクを見つけるには

  • コマンド ライン ビルドの場合: 概要を含めるようにビルドが構成されている場合 (既定値)、その概要は次のようになります。

    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.
    

    この結果は、ファイル S:\MSB6006_demo\MSB6006_demo.csproj の 19 行目に定義されているタスクで、プロジェクト S:\MSB6006_demo\MSB6006_demo.csprojInvokeToolTask というターゲットで、エラーが発生したことを示しています。

  • Visual Studio UI の場合: Visual Studio のエラー一覧の列 ProjectFileLine にも同じ情報が表示されます。

その他のエラー情報を見つける

MSB6006 エラーは、タスクによって特定のエラーがログに記録されなかった場合に生成されます。 エラーをログに記録できない問題は、多くの場合、呼び出したツールから出力されたエラー形式を理解するようにタスクが構成されていないために起こります。

通常、正常に動作するツールからは、標準出力またはエラー ストリームに何らかのコンテキスト情報またはエラー情報が出力され、タスクでは既定でこの情報がキャプチャされ、ログに記録されます。 詳細については、エラーが発生する前のログ エントリを確認してください。 この情報を保持するには、場合によっては、より高いログ レベルでビルドを再実行する必要があります。 うまく行けば、ログで特定された追加のコンテキストまたはエラーから、問題の根本原因が明らかになります。 そうでない場合は、必要に応じて、失敗したタスクに入力されたプロパティと項目を調べて考えられる原因を絞り込みます。

注意

MSBuild では、特定の診断出力形式が認識されます。 この形式の詳細については、「診断メッセージの MSBuild と Visual Studio の形式」を参照してください。

タスクのデバッグ

MSBuild タスクをデバッグするときに役立つ一般的なヒントを以下に示します。

  • 再現ケースのスコープをできる限り絞り込み (たとえば、/p:BuildProjectReferences=false を設定し、1 つの特定のプロジェクトまたは 1 つの特定のターゲットで MSBuild を起動するなど)、操作が必要なコードを減らします。
  • MSBuild コマンド ライン オプション /m:1 を使って、デバッグする単一の MSBuild プロセスを生成します。
  • 環境変数 MSBUILDDEBUGONSTART を 1 に設定し、起動時に MSBuild にアタッチされたデバッガーを取得します。
  • ステップ実行するタスクの Execute メソッドにブレークポイントを設定します。

カスタム タスクのデバッグ

カスタム タスクのコードを記述する場合、タスクの Execute メソッドでデバッガーを呼び出す呼び出しを追加することにより、デバッグしやすくできます。 そのコードを環境変数チェックでフェンスすると、ユーザーがその環境変数を設定したとき、タスクが停止して、ユーザーがデバッグする機会が与えられます。 System.Diagnostics.Debugger.Launch または System.Diagnostics.Debugger.Break を使って、デバッガーを起動したり中断したりできます。

ユーザーがタスクをデバッグしやすいように、カスタム タスクにはできるだけ多くのログ記録を追加してください。 これは、障害の根本原因を最終的に特定する際に重要です。後でその障害モードを検出して報告するのに十分なログ コードを追加します。

xUnit を使ってタスクのテスト環境を設定することを検討してください。 「dotnet テストと xUnit を使用した .NET Core での単体テスト C#」をご覧ください。 問題のタスクを実行するのに必要なプロパティ、項目、ターゲットを含むモック プロジェクト ファイルで、MSBuild API を使って MSBuild をプログラムによって呼び出すよう xUnit テストを構成することができます。 場合によっては、モック ビルド エンジンを作成するのが適切なことがあります。 「Visual Studio を使用したカスタム MSBuild タスクの単体テスト」で例を確認できます。

.NET SDK プロジェクトでは、launchSettings.json を変更し、この記事で前述したコマンド ライン引数と環境変数を使って MSBuild.exe を実行する特殊なデバッグ プロファイル追加することもできます。

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

実行時に独自のデバッガーをアタッチするよう求めるメッセージを表示する場合、環境変数 MSBUILDDEBUGONSTART2 に設定します。 これは、Visual Studio が使用できない macOS など、別のデバッガーを使用する場合に役立ちます。