當前位置: 妍妍網 > 碼農

在 .NET 計畫中復制資源資料夾到生成目錄

2024-03-11碼農

本文主要介紹在使用 Visual Studio 進行偵錯和釋出時,如何在 .NET 計畫中復制資源資料夾到生成目錄。

1. 背景

在開發 .NET 計畫的過程中,我們有時會遇到需要在 debug 、 release 或是釋出時將資源資料夾復制到生成目錄的需求。這些資源可能包括圖片、配置檔、數據檔等。本文將以一個實際計畫為背景,教你如何透過修改計畫檔(.csproj 或 .vbproj)中的 MSBuild 指令來實作這個需求。

在我的計畫中,我正在測試和學習 SemanticKernel,這是一個強大的語意分析工具。其中的外掛程式(plugins)可以以配置檔的方式儲存,如下程式碼所示:

var plugin = kernel.CreatePluginFromPromptDirectory(Path.Combine("plugins", "TranslatePlugin"));

我們使用 VS Code 進行開發時,透過 dotnet run 命令可以方便地看到執行結果,而且沒有復制資料夾的問題。然而,如果改為使用 Visual Studio 進行開發,我們就需要解決資源資料夾在構建時的復制問題。

2. 方法一:逐個添加檔

我們首先可能想到的方法是在 Visual Studio 中手動添加資源資料夾中的檔。這種方法雖然簡單,但是當資源資料夾中的檔較多時,就會變得非常繁瑣。而且,每次添加新檔時,都需要重新操作一遍,雖然透過UI操作容易,但這顯然不是一個好的解決方案。

逐個添加

當我們設定完後,其會自動修改 .csproj(C# 計畫)檔內容,加入如下資訊:

<ItemGroup><NoneUpdate="plugins\TranslatePlugin\Basic\config.txt"><CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory></None></ItemGroup>

3. 方法二:添加 MSBuild 指令

在計畫檔中,我們可以將添加一個新的 MSBuild 目標來完成資源資料夾的復制任務。以下是添加的指令範例:

<ProjectSdk="Microsoft.NET.Sdk"> ...<TargetName="CopyResources"AfterTargets="AfterBuild"><ItemGroup><ResourceFilesInclude="plugins\**"/></ItemGroup><CopySourceFiles="@(ResourceFiles)"DestinationFolder="$(OutDir)\plugins\%(RecursiveDir)"/></Target></Project>

在這個範例中, CopyResources 是一個新的 MSBuild 目標,它在構建完成後執行(由 AfterTargets="AfterBuild" 指定)。 ItemGroup 定義了一個名為 ResourceFiles 的項,包含 plugins 資料夾下的所有檔和子資料夾。 Copy 任務則將這些檔復制到輸出目錄下的 plugins 資料夾。

這種方式雖然在偵錯可以正常工作,但是在釋出時,資源資料夾並不會被復制到釋出目錄。這是因為 AfterBuild 目標只在偵錯時執行,而在釋出時並不會執行。因此,我們需要再添加一個新的規則,將 AfterBuild 替換為 Publish ,同時需要調整輸出資料夾,修改 OutDir PublishDir 以及規則名。這樣,就可以在釋出時復制資源資料夾。修改後需要多添加進計畫檔的資訊如下:

<TargetName="CopyResourcesPublish"AfterTargets="Publish"><ItemGroup><ResourceFilesInclude="plugins\**"/></ItemGroup><CopySourceFiles="@(ResourceFiles)"DestinationFolder="$(PublishDir)\plugins\%(RecursiveDir)"/></Target>

3. 方法三:使用通配符

比較上述兩種方法,我們可以發現,手動添加檔和添加 MSBuild 指令都需要指定資源資料夾中的檔或是需要重復設定,這樣顯然不是一個好的解決方案。我們可以修改自動生成的那段程式碼,使用通配符來簡化這個過程。以下是使用通配符的範例:

<ItemGroup><NoneUpdate="plugins\**"><CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory></None></ItemGroup>

這樣,我們就可以將 plugins 資料夾下的所有檔和子資料夾都復制到輸出目錄。這種方法簡單、直接,而且不需要手動添加檔,非常適合在資源資料夾中的檔較多時使用。

4. 結束語

上述方法提供了一種簡便的方式來在 .NET 計畫中復制資源資料夾,希望這也能幫助到遇到類似問題的你。當然在實際使用中我們可能還需遇到一些更加復雜的需求,比如排查部份,選擇包含等等,這些都可以透過類似的方式來實作。