如何發佈並部署.NET WPF實用工具
[[academy-video-youtube({"vid": "lzGapugz7Jk", "start_time": "0", "title": "How to Publish and Deploy a .NET WPF Utility", "creator": "Tim Corey", "length": "10m 40s"})]]
建立一個小型桌面工具僅僅是工作的一半。 將其放入您的機器中,放置在您可以快速啟動的位置,並保持部署輕巧,以至於您不再需要考慮。這是另一半工作。 太多開發人員過度設計此步驟,為僅在一台工作站上運行的應用程式引入安裝程式框架或跨平台工具。
在他的视频《如何發布和部署.NET WPF工具》中,Tim Corey演示了他如何將自己的影像檢視器應用程式發布為單一可執行檔案,將其複製到文件夾中,並通過註冊表將其連接到Windows右鍵點擊上下文功能表。 我們將涵蓋他在此過程中所做的每個決策,從依賴於框架與自包含構建,到使工具能夠從任何文件夾中存取的註冊表項。 如果您為自己建造了一個小工具並希望獲得最簡單的部署方案,本文將介紹此方法。
從Visual Studio發布
[1:03 - 1:25] Tim首先在Visual Studio中右擊專案並選擇發布。 導引輔助程式提供了幾個目標(Azure、Docker、ClickOnce),但他繞過了所有這些並選擇了文件夾。 對於駐留在您自己機器上的個人工具,文件夾發布是最直接的路徑:它生成您可以在任何需要場所複製的檔案,無需任何部署基礎架構。
選擇文件夾目標後,Tim直接跳到了設置頁面,而不是立即運行發布。 預設設置需要調整,才能匹配他想要的輸出。
依賴框架與自包含
[1:25 - 2:32] 第一個設置是部署模式。 依賴於框架的構建假設.NET SDK 或運行時已安裝在目標機器上。此應用程式的輸出大小小,約為200千字節,因為它依賴於系統上存在的共享運行時。
自包含構建將整個.NET運行時打包到輸出中。 這使得程式包可以在未安裝.NET的機器上使用,但將大小膨脹到約140兆字節。 Tim選擇依賴框架,因為他使用的每台機器上都已安裝.NET。 如果您要將工具分發給可能沒有運行時的同事或客戶,自包含是更安全的選擇,但對於個人工具,這樣的權衡很少有意義。
為何選擇WPF而不是MAUI
[2:50 - 4:10] Tim針對使用WPF而非MAUI開發這個專案的反饋做出回應。 他的理由是實用性而非意識形態。 影像檢視器只需要在Windows上運行。 引入MAUI及其跨平台層會增加負擔,但對於單一平台工具卻沒有任何好處。
除了架構上的論點之外,還有維護角度。 Tim的原始源程式碼在大約七年間跨越了四或五台機器,僅進行了少量更改。 唯一的更新是從.NET Framework升級(到.NET 8,現在到.NET 10)。 如果此工具建置在每當Apple或Google發布操作系統更新時都需要注意的框架上,那麼七年來抽身操作是不可能的。 一個需要更多時間維護而不是節省時間的工具已經不再為您節省任何東西。
單文件發布和PDB檔案
[4:59 - 6:32] 部署模式確定後,Tim啟用了"生成單一檔案"並目標設為Windows x64。發布完成並打開輸出文件夾,其中包含兩個文件:.pdb。
第二個文件是程式資料庫文件,了解其作用是值得的。 當您在Release模式下編譯時,編譯器會進行優化並重命名內部符號以提高性能。 PDB將這些優化過的名稱映射回您的實際程式碼庫,使您能夠將除錯器附加到正在運行的可執行檔案並設置斷點,如同您在Debug模式下作業一樣。 對於服務客戶的生產應用程式,您應該將PDB文件安全地儲存在每個版本旁邊,以便在部署後診斷問題。
對於您自己構建的工具,Tim表示應用程式運行不需要PDB。 他為了簡單删除了它,但提醒觀眾不要形成這個習慣,發送給使用者的任何東西都不應這樣做。 單一.exe即使在沒有PDB的情況下也可以獨立運行。
有一個值得注意的怪異現象:如果您從依賴框架切換到自包含並保持"單文件"啟用,則輸出不再是單一文件。額外的運行時檔案會與可執行檔案一起出現。 只有當與依賴框架的構建搭配時,單文件選項才會生成真正的單一文件。
將工具放置在您的機器上
[7:17 - 7:52] 取得可執行檔案後,Tim將其移動到永久位置。 他使用專用的C:\Apps\SimpleImageViewer文件夾,這種慣例使個人工具與程式文件分開,且易於查找。 2024年的可執行檔案在他目前的機器上仍然完全運行,這進一步證實了早先關於長壽命的觀點:一個良好定範圍的工具與簡單的專案結構可以在不進行修改的情況下經受住硬體更換和操作系統升級。
將工具新增到右鍵功能表
[7:52 - 10:21] 最後一步是在Windows Explorer的上下文功能表中連接工具。 Tim修改Windows註冊表,在兩個位置下新增項:一個是右擊文件夾時(這樣您可以打開目錄中的影像),另一個是右擊文件夾中的空白處(以在當前目錄中啟動檢視器)。
每個註冊表項建立一個shell命令,將所選路徑作為命令行參數傳遞給可執行文件。 這是應用程式入口點中的args參數接收其值的地方。
Tim提供了一個.txt。 這一點很重要:雙擊.reg文件會立即提示寫入值進入註冊表,運行未受信任的註冊表文件會導致嚴重系統問題。 他的做法要求您打開文件,驗證路徑,將其更新為與您的機器匹配,然後將擴展名重新更改為.reg,然後才能驅動它。 如果其中有任何聽起來不熟悉,Tim的建議很直接:不要修改註冊表。
對於習慣於處理註冊表的開發人員,這兩個條目都很簡單。 每一個在適當的關鍵下建立一個命名的shell命令,指向您可執行檔案的完整路徑,以及一個%1佔位符,在運行時傳遞目標目錄或文件路徑。可能需要重新啟動才能使新的上下文功能表項目顯示。
總結:一次部署,永遠使用
[10:21 - 10:30] 整個部署過程只有兩步:發布到文件夾,然後在右鍵功能表中註冊可執行檔案。 沒有安裝程式,沒有更新機制,沒有雲服務。對於在您自己機器上的單一用途工具,這種簡單就是重點。
結論
[10:30 - 10:40] 總結:dotnet publish使用框架依賴與單文件設置,生成一個輕巧的可執行檔案,您可以將其放置在任何地方。 一對註冊表條目將其轉換成在Windows Explorer中的上下文功能表動作。
整個影片貫穿的教訓是節制。 將您的部署方法與應用程式的範圍相匹配。 一個為個人使用而建的工具不需要與發送給數千位客戶的產品相同的基礎設施,這樣對待它只會創造出令工具建置來節省的時間的維護工作。
範例提示:即使是個人項目,也請保留您的PDB文件。 將它們存放在與可執行文件相同的文件夾或附近的存檔中。如果工具在幾個月後行為不正常,擁有PDB讓您能夠附加Visual Studio並除錯發行版本,而無需從源程式碼重新編譯。

