ビルド イベントを指定する (C#)

ビルド開始前またはビルド終了後に実行するコマンドを指定するには、ビルド イベントを使います。

ビルド イベントを指定する

  1. ソリューション エクスプローラーで、ビルド イベントを指定するプロジェクトを選択します。

  2. [プロジェクト] メニューの [プロパティ] をクリックします。

  3. [ビルド イベント] タブを選択します。

  4. [ビルド前に実行するコマンド ライン] ボックスで、ビルド イベントの構文を指定します。

    Note

    プロジェクトが最新の状態で、ビルドがトリガーされない場合、ビルド前イベントは実行されません。

  5. [ビルド後に実行するコマンド ライン] ボックスで、ビルド イベントの構文を指定します。

    Note

    .bat ファイルを実行するすべてのビルド後コマンドの前に call ステートメントを追加します。 たとえば、call MyFile.bat または call MyFile.bat call MyFile2.bat です。 パスは、絶対パスまたはプロジェクト フォルダーに対する相対パスにすることができます。

  6. [ビルド後イベントの実行] ボックスで、ビルド後イベントを実行する条件を指定します。

    Note

    長い構文を追加する場合、または [ビルド前に実行するコマンド ライン]/[ビルド後に実行するコマンド ライン] ダイアログ ボックスでビルド マクロを選択する場合は、省略記号 [...] ボタンをクリックして編集ボックスを表示します。

  1. ソリューション エクスプローラーで、ビルド イベントを指定するプロジェクトを選択します。

  2. [プロジェクト] メニューで、[{ProjectName} のプロパティ] をクリックします (または、ソリューション エクスプローラーから、Alt+Enter キーを押します)。

  3. [ビルド] > [イベント] を選択します。

    ビルド イベントの設定を示すスクリーンショット。

  4. [ビルド前のイベント] セクションで、ビルド イベントの構文を指定します。

    注意

    プロジェクトが最新の状態で、ビルドがトリガーされない場合、ビルド前イベントは実行されません。

  5. [ビルド後のイベント] セクションで、ビルド イベントの構文を指定します。

    注意

    .bat ファイルを実行するすべてのビルド後コマンドの前に call ステートメントを追加します。 たとえば、call MyFile.bat または call MyFile.bat call MyFile2.bat です。 パスは、絶対パスまたはプロジェクト フォルダーに対する相対パスにすることができます。

  6. [When to run the post-build event](ビルド後のイベントをいつ実行するか) セクションで、ビルド後のイベントを実行する条件を指定します。

ビルド イベント コマンドを作成する

ビルド イベント コマンドでは、コマンド プロンプトまたは .bat ファイルで有効な任意のコマンドを使うことができます。 後続のすべてのコマンドが確実に実行されるように、バッチ ファイルの名前の前には call を記述する必要があります。 バッチ ファイル自体は、出力フォルダー (例: bin/Debug) から実行されます。 すべての構成に同じバッチ ファイルが必要な場合は、プロジェクト ファイルと同じフォルダーに配置し、call ../../prebuild.bat などの相対パスを使用できます。

PowerShell MyPowerShellScript.ps1 などのコマンドを入力することで、PowerShell スクリプトを実行できます。 PowerShell スクリプトへのパスは絶対パスにするか、プロジェクト ディレクトリに対する相対パスにすることができます。 スクリプトを実行するには、オペレーティング システム上の PowerShell スクリプトの実行ポリシーが適切に設定されていることを確認する必要があります。 実行ポリシーに関するページを参照してください。

bash などの別のシェルを使用する場合は、通常、Windows コマンド プロンプトからシェル スクリプトを起動する場合と同じコマンド構文を使用します。 サードパーティ製のシェルの使用についてはこのドキュメントでは取り上げませんが、Stack Overflow などのサイトが役に立つ場合があります。

プロジェクト ファイルで

前の手順を実行すると、Visual Studio で、PreBuild または PostBuild ターゲットと、指定した手順を実行するために必要な MSBuild コードが追加されることで、プロジェクト ファイルに変更が加えらえれます。 プロジェクト ファイルを開いて、その手順を確認することができます。 プロジェクト ファイルの手順は変更しても問題ありません。 変更を保存した後は、プロジェクトのプロパティの [ビルド] > [イベント] セクションで、加えた変更を確認できます。

<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
  <Exec Command="call prebuild.bat" />
</Target>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
  <Exec Command="call postbuild.bat" />
</Target>

Exec 要素は MSBuild Exec タスクを参照します。 実行のカスタマイズに使用できるその他のパラメーターについては、「Exec タスク」を参照してください。 たとえば、実行可能ファイルの実行元フォルダーを設定するために WorkingDirectory を使用できます。 既定値は、プロジェクト ファイルが含まれるディレクトリです。

<Exec Command="call prebuild.bat" WorkingDirectory="$(OutDir)">

この記事の「マクロ」で後述されているように、前の例にある OutDir のような MSBuild プロパティ (マクロ) を使用できます。

エラーとその他の出力

ビルド イベントの出力は、出力ウィンドウ[ビルド] セクションに書き込まれます。 これを開くには、[表示]>[Other Window] (その他のウィンドウ)[出力ウィンドウ] の順に選択するか、Ctrl+Alt+O キーを押します。 [出力元の表示] の横にあるドロップダウンで、[ビルド] を選択します。

ビルド前またはビルド後イベントが正常に完了しない場合は、ゼロ (0) 以外のコードでイベント アクションを終了させて、ビルドを終了することができます。 ゼロ終了コードは正常なアクションを示します。その他の終了コードはエラーと見なされます。

ビルド前イベントが失敗した場合は、[エラー一覧] ウィンドウに次のようなエラーが表示されることがあります。

MSB3073    The command "call c:\source\repos\prebuild.bat" exited with code 1.

[エラー一覧] ウィンドウに十分な情報がない場合は、出力ウィンドウを使用して、バッチ ファイルからのすべての出力が含まれる、完全なビルド出力を確認することができます。

ヒント

[エラー一覧] ウィンドウは、イベントに入力した最初の行である 1 行の出力のみに制限されます。 [エラー一覧] ウィンドウの出力が重要な場合は、イベントに複数の行を含めることは避けてください。 Windows コマンド プロンプトまたはオペレーティング システムからバッチ ファイルを作成し、そのイベントにだけ call mybatchfile.bat を使用します。 コマンドをバッチ ファイル自体に含めます。

バッチ ファイルで使用できるコマンドのガイダンスについては、「Windows のコマンド」を参照してください。

マクロ

一般に使用できる "マクロ" (実際には MSBuild のプロパティ) は MSBuild 共通プロパティに関するページに記載されています。 .NET SDK プロジェクト (.NET Core または .NET 5 以降) の場合、追加のプロパティは「Microsoft.NET.Sdk の MSBuild プロパティ」に記載されています。

ビルド イベントのスクリプトでは、プロジェクトの名前や出力フォルダーの場所など、一部のプロジェクトレベルの変数の値を参照することができます。 以前のバージョンの Visual Studio では、これらは マクロ と呼ばれていました。 最近のバージョンの Visual Studio では、マクロに相当するものは MSBuild プロパティです。 MSBuild は、Visual Studio がビルドを実行するときにプロジェクト ファイルの処理に使われるビルド エンジンです。 IDE のビルド イベントは、プロジェクト ファイル内の MSBuild ターゲットになります。 プロジェクト ファイルのターゲットで使用可能な任意の MSBuild プロパティ (たとえば、$(OutDir) または $(Configuration)) を使うことができます。 これらのイベントで使用できる MSBuild プロパティは、.props.targets ファイルなどプロジェクト ファイルに暗黙的または明示的にインポートされたファイルや、PropertyGroup 要素などプロジェクト ファイルに設定されたプロパティに依存します。 各プロパティのスペルが正確になるように注意してください。 プロパティのスペルを間違えてもエラーにはなりません。その代わり、未定義のプロパティは空文字列として評価されます。

たとえば、ビルド前のイベントを次のように指定するとします。

ビルド前のイベントの例を示すスクリーンショット。

このビルド前のイベントは、次のようにプロジェクト ファイルの Target というエントリになります。

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="echo Configuration: $(Configuration)&#xD;&#xA;echo DevEnvDir: $(DevEnvDir)&#xD;&#xA;echo OutDir: $(OutDir)&#xD;&#xA;echo ProjectDir: $(ProjectDir)&#xD;&#xA;echo VisualStudioVersion: $(VisualStudioVersion)&#xD;&#xA;echo AssemblySearchPaths: $(AssemblySearchPaths)&#xD;&#xA;echo AssemblyName: $(AssemblyName)&#xD;&#xA;echo BaseIntermediateOutputPath: $(BaseIntermediateOutputPath)&#xD;&#xA;echo CscToolPath: $(CscToolPath)" />
  </Target>

ビルド イベントは、Command として指定した入力と共に Exec タスクを含むターゲットとして表示されます。 改行は XML でエンコードされます。

この例でプロジェクトをビルドすると、ビルド前イベントでいくつかのプロパティの値が出力されます。 この例では、$(CscToolPath) は定義されていないため、何も出力されません。 これは省略可能なプロパティであり、C# コンパイラのカスタマイズされたインスタンスへのパスを指定するために、プロジェクト ファイル内で定義できます (たとえば、異なるバージョンの csc.exe、または実験用のコンパイラをテストしている場合など)。

ビルド イベントの出力はビルド出力に書き込まれ、 [出力] ウィンドウに表示されます。 [出力元の表示] ドロップダウンで、 [ビルド] を選びます。

Build started...
1>------ Build started: Project: ConsoleApp4, Configuration: Debug Any CPU ------
1>You are using a preview version of .NET. See: https://aka.ms/dotnet-core-preview
1>Configuration: Debug
1>DevEnvDir: C:\Program Files\Microsoft Visual Studio\2022\Preview\Common7\IDE\
1>OutDir: bin\Debug\net6.0\
1>ProjectDir: C:\source\repos\ConsoleApp4\ConsoleApp4\
1>VisualStudioVersion: 17.0
1>ALToolsPath:
1>AssemblySearchPaths: {CandidateAssemblyFiles};{HintPathFromItem};{TargetFrameworkDirectory};{RawFileName}
1>AssemblyName: ConsoleApp4
1>BaseIntermediateOutputPath: obj\
1>CscToolsPath:
1>Skipping analyzers to speed up the build. You can execute 'Build' or 'Rebuild' command to run analyzers.
1>ConsoleApp4 -> C:\source\repos\ConsoleApp4\ConsoleApp4\bin\Debug\net6.0\ConsoleApp4.dll

注意

一部のシナリオでは、ビルド イベントで実行できるものよりも、より複雑なビルド アクションが必要です。 たとえば、多くの一般的なコード生成シナリオでは、クリーン操作とリビルド操作を処理する必要があります。また、コード生成手順に対してインクリメンタル ビルドを有効にし、入力に関して出力が古くなっている場合にのみ手順を実行するようにすることができます。 MSBuild は、これらのすべてのシナリオをインテリジェントに処理するように設計されています。 AfterTargets または BeforeTargets を指定し、ビルド プロセスの特定の時点で実行するカスタム ターゲットを作成することを検討してください。また、高度なシナリオでさらに制御するために、カスタム タスクを作成することを検討するか、ビルドをカスタマイズできる別の方法を確認してください。

  1. プロジェクト フォルダーに、次のような内容の postbuild.bat という名前のバッチ ファイルを作成します。

    echo Copying output file %1 to %1.copy
    copy %1 %1.copy
    

    バッチ ファイルにおいて、%1 は渡された最初の引数を指すことを思い出してください。

  2. プロジェクト プロパティの [ビルド後のイベント] セクションでそのバッチ ファイルを呼び出し、MSBuild プロパティ $(TargetPath) を使用して引数を渡します。

    call postbuild.bat $(TargetPath)
    
  3. プロジェクトをビルドし、出力フォルダーを確認します。 ビルドされたアセンブリの横に、コピーしたファイルが表示されます。 出力ウィンドウ[ビルド] セクションに、バッチ ファイルの出力が表示されます。

    1>Output file is C:\source\repos\ConsoleApp-BuildEvents\ConsoleApp-BuildEvents\bin\Debug\net6.0\ConsoleApp-BuildEvents.dll
    1>        1 file(s) copied.
    ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
    ========== Build started at 12:00 PM and took 00.723 seconds ==========