指定建置事件 (C#)

使用建置事件來指定在建置開始之前或建置完成之後執行的命令。

指定建置事件

  1. 在 [方案總管]中,選取您要指定建置事件的專案。

  2. 在 [專案] 功能表上,按一下 [{ProjectName} 屬性](或從 [方案總管],按下 [Alt+Enter])。

  3. 選擇 [建置 > 事件。

    顯示 [建置事件] 設定的螢幕快照。

  4. 在 [建置前事件] 區段中,指定建置事件的語法。

    注意

    如果專案為最新狀態且未觸發任何建置,則建置前事件不會執行。

  5. 在 [建置後事件] 區段中,指定建置事件的語法。

    注意

    在執行 call 檔案的所有建置後命令之前,新增 語句。 例如,call MyFile.bat 或 call MyFile.bat call MyFile2.bat。 路徑可以是絕對路徑,或相對於輸出資料夾。

  6. 在 [何時執行建置後事件 區段,指定要在哪些條件下執行建置後事件。

建立建置事件指令

建置事件命令可以包含任何在命令提示字元或 .bat 檔案中有效的命令。 可用的命令記載於 Windows 命令參考中。 批處理文件的名稱前面應加上 call,以確保所有後續命令都會執行。 批次處理檔案本身會從輸出資料夾執行,例如,bin/Debug。 如果您需要所有組態的相同批次處理檔,您可以將它放在與項目檔相同的資料夾中,並使用相對路徑,例如,call ../../prebuild.bat。

您可以輸入類似 的命令,以執行 PowerShell MyPowerShellScript.ps1 腳本。 PowerShell 腳本的路徑可能是絕對路徑,或可能相對於項目目錄。 您必須確定操作系統上 PowerShell 腳本的執行原則已適當設定,才能執行腳本。 請參閱 關於執行原則。

如果您想要使用其他 Shell,例如 bash,通常會使用與從 Windows 命令提示字元啟動 Shell 腳本相同的命令語法。 使用第三方 shell 超出本文件的範圍,但像 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)">

您可以使用 MSBuild 的屬性(亦即巨集),例如如本文稍後在 OutDir部分所討論的上一個範例中的 。

錯誤及其他輸出

建置事件的輸出會寫入至 輸出視窗的 組建 區段。 若要開啟它,請選擇 [檢視]>[其他 Windows]、[輸出視窗],或按 Ctrl ++Ctrl。 在[顯示輸出]旁的下拉式清單中,選擇[建置]。

如果您的建置前或建置後事件未順利完成,您可以讓事件動作使用非零的程式代碼終止建置。 零結束代碼表示成功的動作;任何其他結束代碼都會被視為錯誤。

如果您的建置前事件失敗,您可能會在 [錯誤清單] 視窗中看到如下的錯誤:

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

如果 錯誤清單 視窗中沒有足夠的資訊,您可以嘗試使用 [輸出視窗] 來檢視完整的組建輸出,包括批處理檔的任何輸出。

提示

錯誤清單 視窗僅限於一行輸出,這是您為事件輸入的第一行。 如果 錯誤清單 視窗輸出對你很重要,請避免在事件中放置多於一行的內容 。 從 Windows 命令提示字元或在作業系統中建立批處理檔,然後只針對 事件使用 call mybatchfile.bat。 在批處理檔中包含命令。

如需您可以在批次處理檔中使用的命令指引,請參閱 Windows 命令。

巨集

常見的「巨集」(實際上指的是 MSBuild 屬性)列在 MSBuild 通用屬性。 針對 .NET SDK 專案(.NET Core 或 .NET 5 和更新版本),其他屬性會列在 MSBuild 屬性和Microsoft.NET.Sdk 中。

在建置事件的腳本中,您可能想要參考某些專案層級變數的值,例如專案的名稱或輸出資料夾的位置。 在舊版的 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>

建置事件顯示為一個目標,其中包含 Exec 工作,並以您指定的輸入作為 Command。 換行符會以 XML 編碼。

當您在此範例中建置專案時,建置前事件會列印某些屬性的值。 在此範例中,$(CscToolPath) 不會產生任何輸出,因為它未定義。 這是選擇性屬性,您可以在項目檔中定義,以提供 C# 編譯程式自定義實例的路徑(例如,如果您正在測試不同版本的 csc.exe或實驗性編譯程式)。

建置事件的輸出會寫入建置輸出,您可以在 Output 視窗中找到。 在 顯示輸出來源 下拉式清單中,選擇 建置。

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

  1. 輸入複製命令,將建置輸出複製到另一個資料夾。

    xcopy "$(TargetDir)*.*" "C:\Drop\$(Configuration)\" /E /Y
    

    此命令會參考 MSBuild 屬性 TargetDir 和 Configuration。 請注意引號的使用,這是處理帶有空格的路徑所必需的。

  2. 結束「性質設計器」並建置。 輸出檔案應複製到子資料夾下的C:\Drop目的地資料夾Configuration。

  3. 在 [輸出] 視窗中,使用下拉式清單切換至檢視 建置 輸出,並查看呼叫命令的位置 xcopy 。 如果您看到錯誤,請確認您的使用者帳戶具有該位置的寫入權限。

範例 2

  1. 在專案資料夾中建立名為 postbuild.bat 的批處理檔,其中包含下列內容:

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

    回想一下,在批處理檔中,%1 參考傳入的第一個自變數。

  2. 在專案屬性的 Post-build 事件 區段中呼叫批處理檔,並使用 MSBuild 屬性 $(TargetPath)傳遞自變數。

    call postbuild.bat $(TargetPath)
    

    如果您需要在批次檔中使用 MSBuild 屬性 (巨集) 的值,您可以將它作為引數傳遞,如此處所示。

  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 ==========