抱歉,您的瀏覽器無法訪問本站
本頁面需要瀏覽器支持(啟用)JavaScript
了解詳情 >

從以前的 .NET Framework 到現在最新的 .NET 框架,所編譯出的結果已經有些不同。以 .NET 框架的 WPF 專案為例,編譯後最少會生成一組 exe 執行檔與對應的 DLL 。

而現代程式在開發時,經常會使用各種套件或自行撰寫的類別庫來加快開發速度,所以使用的越多,編譯出來的執行檔旁邊的 DLL 檔也越多。

而在一些情況下,會將整個編譯輸出的資料夾壓縮後交付給使用者。不過,當檔案數量過多時,使用者在複製或移動時可能會遺漏,甚至誤刪必要的 DLL。若能將專案打包成單一執行檔,這些問題便能避免。

本篇將紀錄在 .NET WPF 專案中產生單一執行檔的可行方案之一,方便日後做參考。

本次的開發環境,如下

  • IDE : Visual Studio 2022
  • .NET版本 : .NET 8.0

專案輸出現況

首先來回顧一下現有的狀況。

當建立一個新的 .NET WPF 專案並進行編譯後,在 bin 資料夾中,若沒有特別設定,通常會看到與專案名稱相同的 exe,以及一個對應的 DLL。

.NET WPF 專案編譯輸出結果


若專案透過 NuGet 引入了套件,編譯結果中則會多出這些套件所需的 DLL。若該套件依賴多個 DLL,資料夾裡的檔案數量也會隨之增加。

.NET WPF 專案使用 NuGet 套件後,編譯輸出結果


那麼在 .NET 框架下,透過專案內建的機制,搭配一些設定,便可產生單一執行檔。

設定與操作流程

準備好 WPF 專案後,實際的操作並不複雜,只需要依照以下步驟,就能在本地產生單一執行檔。

需要注意的是,這些設定只在第一次進行時才需要,之後會隨著專案一併保存,不需重複設定。

  1. 在專案上按下右鍵,於選單的上半部點選 「發佈」。

在專案點選右鍵選單,並選取發佈選項


  1. 在「目標」設定中,因要發佈到本機,選擇 「資料夾」,再點選 「下一步」。

發佈設定的目標設定步驟


  1. 在「特定目標」設定中,同樣選擇 「資料夾」,並繼續點選 「下一步」。

發佈設定的特定目標設定步驟


  1. 在「位置」設定中,個人通常使用預設的相對路徑,所以無需額外調整,直接按下 「完成」。

發佈設定的位置設定步驟


  1. 系統會自動建立發行設定檔,完成後點選 「關閉」。

發佈設定的建立完成畫面


  1. 接著回到發佈畫面,針對要產生的執行檔進行設定,點選下方的 「顯示所有設定」。

發佈設定的設定成城後的發佈畫面


  1. 在設定檔視窗中,預設值如左圖所示:
    • 組態 和 目標 Framework 依照專案需求設定。
    • 將「目標執行階段」由 可攜式 改為 win-x86,或視需求可改為 win-x64。
    • 在下方的「檔案發行選項」中,勾選 「產生單一檔案」。
    • 最後點選 「儲存」。

設定檔設定前後畫面


到這裡,相關的設定就完成了。

發佈結果

不論是首次完成設定,或是已經建立好發佈設定檔,之後只需要在專案上按右鍵並選擇 「發佈」,即可進入發佈頁面。

在該頁面中按下 「發佈」 按鈕後,系統會進行編譯並產生輸出檔案。完成後,若想直接開啟輸出位置,只要點選 「巡覽」,即會自動開啟對應的資料夾。

程式本地資料夾發佈步驟


進入 publish 資料夾後,可以看到輸出的結果僅有一個 exe 執行檔。
所有原本的 NuGet 相依 DLL 都已被打包進執行檔中,因此資料夾中沒有額外出現這些檔案。需要注意的是,這項處理僅適用於 .NET 的 DLL。

使用發佈功能所編譯出的結果演示


再來只要使用者的電腦上有安裝相對應版本的 .NET Runtime,即可直接執行該程式。

另外,若有需求,也能在發佈完成後,針對輸出的執行檔進行數位簽章。

補充

部屬模式最後選擇使用 Framework 相依性,是經過一些排列組合測試後個人的選擇。

這邊備忘紀錄一下,選擇部屬模式為獨立式的結果,而其他設定如下圖,

在部署模式的選擇上,最後個人選擇使用 Framework 相依性。

這是經過多個測試不同組合後的結果,因此在這裡也順便做個備忘紀錄。

若改成「獨立式部署」,其設定如下圖:

發佈設定檔設定部屬模式獨立式的畫面


編譯完成後,到 publish 資料夾中可以看到以下情況:

  • 同樣會有專案的執行檔,且仍然沒有 NuGet 相依的 DLL。
  • 執行檔的大小,從 Framework 相依性約 10MB,膨脹到 150MB 左右。
  • 此外還會額外產生許多 DLL,個人推測這些應該是 C++ 相依的 DLL。

發佈設定檔設定部屬模式獨立式的輸出結果


因此,即使有勾選「產生單一檔案」,最終結果還是會因部署模式的不同而產生差異。

自言自語543

進到 .NET 架構之後,甚至在使用 NuGet 已經成為主流 (應該?) 的現在,

整體情況跟當年 .NET Framework 的時代,已經有不少差異。

在想要把程式打包成單一執行檔的過程中,

意外發現這項功能還算方便。

雖然使用者端仍需要安裝對應的 Runtime,

看起來並不是最完美的解法,

但在某些情境下其實已經夠用。

當然,還是會遇到一些限制,

例如套件裡若有使用到 C++ 的 DLL (也就是非 .NET 的 DLL),

就無法透過本文的方法被打包進去。

又或者有人認為,比起單一執行檔,

把所有需要的東西都包進安裝檔,

再透過安裝程序來解決 DLL 散落的問題,

可能才是更好的做法,

若是這樣可以考慮 MSIX。

至於要怎麼把 C++ DLL 包進執行檔,或是進一步使用 MSIX,

那又是另外一段故事了……

未來有機會再另外做分享吧 (?)

評論




本站使用 Volantis 作為主題,總訪問量為