用交付總卡在缺運(yùn)行環(huán)境?.NET Windows Desktop Runtime 把安裝包這件小事做完了)
Windows桌面應(yīng)用交付總卡在缺運(yùn)行環(huán)境.NET Windows Desktop Runtime 把安裝包這件小事做完了【免費(fèi)下載鏈接】windowsdesktop項(xiàng)目地址: https://gitcode.com/gh_mirrors/wi/windowsdesktop把編譯好的 WinForms 程序發(fā)給客戶雙擊卻彈出 To run this application, you must install .NET。這一句話幾乎每個(gè)做 Windows 桌面應(yīng)用部署的開(kāi)發(fā)者都見(jiàn)過(guò)。別急著背鍋——你缺的不是技術(shù)而是一個(gè)能把 WinForms 與 WPF 運(yùn)行時(shí)完整打包、隨應(yīng)用一起分發(fā)的開(kāi)源項(xiàng)目.NET Windows Desktop Runtimewindowsdesktop 倉(cāng)庫(kù)。本文不羅列功能清單只回答三個(gè)真實(shí)問(wèn)題用戶電腦是裸機(jī)怎么辦兩個(gè)桌面框架怎么保證版本一致老用戶怎么平滑升級(jí)每一道題都能在倉(cāng)庫(kù)源碼里找到對(duì)應(yīng)的解法。難題一用戶機(jī)器上啥都沒(méi)有運(yùn)行環(huán)境從哪來(lái)把應(yīng)用比作鑰匙運(yùn)行時(shí)就是鎖芯適配器——鑰匙再好沒(méi)有適配器也擰不動(dòng)鎖。傳統(tǒng)做法是讓用戶先手動(dòng)裝 .NET Framework然后祈禱他別裝錯(cuò)版本、別點(diǎn)到舊鏈接。這個(gè)項(xiàng)目的解法在src/windowsdesktop/src/bundle/目錄用 WiX 生成安裝引導(dǎo)程序bundle。打開(kāi)bundle.wxs你會(huì)發(fā)現(xiàn)它不是一個(gè)下一步—下一步的空殼而是把版本判斷、架構(gòu)檢查、升級(jí)關(guān)系全寫(xiě)進(jìn)了安裝邏輯。比如它通過(guò)注冊(cè)表與文件系統(tǒng)搜索dotnet.exe的實(shí)際位置檢測(cè) x86 與 ARM64 的安裝路徑?jīng)_突避免同一臺(tái)機(jī)器出現(xiàn)兩套互不認(rèn)識(shí)的運(yùn)行時(shí)。最終產(chǎn)出一個(gè)帶界面的單文件安裝包雙擊即裝用戶全程不需要理解運(yùn)行時(shí)是什么。難題二WinForms 和 WPF 各自維護(hù)怎么保證打的是一套運(yùn)行時(shí)WinForms 和 WPF 由兩個(gè)獨(dú)立倉(cāng)庫(kù)維護(hù)若各打各的包版本錯(cuò)位是遲早的事。該項(xiàng)目把兩者收編進(jìn)src/windowsdesktop/src/sfx/由兩個(gè)工程統(tǒng)一產(chǎn)出Microsoft.WindowsDesktop.App.Ref引用程序集隨 .NET SDK 自動(dòng)引用新建 WinForms/WPF 項(xiàng)目即可直接使用命名空間Microsoft.WindowsDesktop.App.Runtime負(fù)責(zé)運(yùn)行時(shí)要分發(fā)的全部?jī)?nèi)容。WindowsForms.Packaging.targets里的校驗(yàn)邏輯更有意思構(gòu)建前會(huì)檢查Microsoft.Private.Winforms包中的FileClassification.props和 analyzer 是否齊全缺一個(gè)直接報(bào)錯(cuò)把裝了一半的包攔在發(fā)布之前。難題三老用戶要升級(jí)、海外用戶看不懂英文怎么處理bundle.wxs中有一段RelatedBundle升級(jí)關(guān)系定義了 preview → RC → GA → 服務(wù)更新servicing的完整升級(jí)鏈路——用戶無(wú)需先卸載舊版新版安裝包會(huì)主動(dòng)接管并替換。安裝器同時(shí)支持/install、/repair、/uninstall、/layout等命令行參數(shù)企業(yè)可以用腳本批量靜默部署配合/quiet、/passive。多語(yǔ)言方面bundle/theme/目錄按 LCID 劃分了 14 套本地化文件1033 英文、2052 簡(jiǎn)體中文、1028 繁體中文、1031 德文、1041 日文、1042 韓文、1049 俄文等。每套thm.wxl控制安裝向?qū)У陌粹o文案與提示語(yǔ)整體界面樣式由bundle.thm統(tǒng)一驅(qū)動(dòng)——想定制品牌色或按鈕布局改這兩個(gè)文件即可。 動(dòng)手驗(yàn)證把安裝包構(gòu)建鏈路跑起來(lái)想親眼看看這套打包邏輯克隆倉(cāng)庫(kù)git clone https://gitcode.com/gh_mirrors/wi/windowsdesktop重點(diǎn)看三處src/windowsdesktop/src/bundle/安裝包、src/windowsdesktop/src/sfx/運(yùn)行時(shí)打包、根目錄的Build.proj與WindowsDesktop.sln構(gòu)建入口。CI 流程在azure-pipelines.yml中定義。倉(cāng)庫(kù)還自帶tests/目錄NuGetArtifactTester.cs會(huì)下載構(gòu)建產(chǎn)物并校驗(yàn)程序集完整性。具體構(gòu)建參數(shù)與依賴版本以倉(cāng)庫(kù)內(nèi)文檔及官方發(fā)布說(shuō)明為準(zhǔn)。?? 三個(gè)容易踩的坑源碼里其實(shí)已寫(xiě)了答案別假設(shè)所有 DLL 都有版本號(hào)。sfx/Directory.Build.props顯式放行了PenImc_cor3.dll、wpfgfx_cor3.dll等原生組件——它們沒(méi)有 FileVersion 卻必須進(jìn)入安裝包。如果你的發(fā)布腳本對(duì)版本號(hào)做強(qiáng)校驗(yàn)這類(lèi)文件會(huì)靜默漏掉。安裝路徑不能拍腦袋。bundle 會(huì)區(qū)分 x86/ARM64 的 Program Files 路徑并做相似性比對(duì)手動(dòng)改安裝目錄前先看bundle.wxs里的條件邏輯。升級(jí)不等于卸載重裝。善用/layout生成離線副本配合穩(wěn)定不變的 UpgradeCode才能覆蓋預(yù)覽版到正式版的過(guò)渡場(chǎng)景。結(jié)語(yǔ).NET Windows Desktop Runtime 做的事其實(shí)很樸素把 WinForms/WPF 運(yùn)行時(shí)的打包、多語(yǔ)言、升級(jí)、架構(gòu)兼容一次性做好讓安裝即用成為默認(rèn)體驗(yàn)。下次再有人問(wèn) Windows 桌面應(yīng)用部署為什么這么省心答案就藏在這個(gè)倉(cāng)庫(kù)的 bundle 與 sfx 兩個(gè)目錄里?!久赓M(fèi)下載鏈接】windowsdesktop項(xiàng)目地址: https://gitcode.com/gh_mirrors/wi/windowsdesktop創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考