Windows 應用程式散發方式怎麼選 - MSI/MSIX/ClickOnce/xcopy/自訂更新

· 更新日期: · · Windows, 發布, MSI, MSIX, ClickOnce, xcopy, updater

更新紀錄(2 筆,最後更新 2026年09月04日)

本文的修改紀錄。已保存的更新前版本,可透過附有 DOI 的永久連結閱讀。

已將繁體中文版改寫為日文原文的完整翻譯。先前的繁體中文版只譯出日文原文的一部分,遺漏了章節、表格、Mermaid 圖、圖說與 FAQ。本次依日文原文將這些內容全部補回,並新增本文的知識地圖章節。技術主張與日文版一致。 查看更新前的版本 (DOI: 10.5281/zenodo.22279483)
補上了日文原文中已有的諮詢引導(consultation_services)。內文沒有改動。 查看更新前的版本 (DOI: 10.5281/zenodo.21616341)
初次發布
引用本文(DOI: 10.5281/zenodo.21616340)

本文保存於 Zenodo。以下同時提供一律指向最新版本的 DOI,以及固定於您正在閱讀版本的 DOI。

Go Komura(2026)。〈Windows 應用程式散發方式怎麼選 - MSI/MSIX/ClickOnce/xcopy/自訂更新〉。小村軟體有限公司。https://doi.org/10.5281/zenodo.21616340 https://comcomponent.com/zh-TW/blog/2026/03/20/000-windows-app-deployment-msi-msix-clickonce-xcopy-custom-updater/

DOI(最新版本)
10.5281/zenodo.21616340
DOI(此版本)
10.5281/zenodo.22297181

下載附日文與英文工作表的 Excel 判斷工作表

要決定 Windows 應用程式的散發方式時,話題常常從「哪一個比較新」「哪一個比較簡單」開始。 但實務上真正管用的,是另一組軸線。

  • 想以使用者為單位安裝,還是要裝到整台機器
  • 更新要交給散發平台,還是自己扛
  • 有沒有服務 / 驅動程式 / shell extension / COM 註冊這類 OS 整合
  • 需不需要撐得住封閉網路、離線、USB 散發
  • 需不需要 package identity,還是想以純 Win32 的身分 unrestricted 地跑

散發方式的選擇,不是 installer 格式的偏好,而是 要動到 OS 多深 與 更新責任由誰扛 的選擇。

決定散發方式的兩條軸線說明散發方式的選擇不是哪一個比較新或比較簡單這種 installer 格式的偏好,而是要動到 OS 多深,以及更新責任由誰扛這兩條軸線的選擇的圖。「哪一個比較新、比較簡單」這條軸線決定不了要動到 OS 多深散發方式就定下來更新責任由誰扛

圖 1: 散發方式不是靠偏好,而是由 OS 整合的濃度與更新責任這兩條軸線決定。

這篇文章是寫給 正在做 Windows 桌面應用程式,接下來要決定散發方式,或想重新檢視目前方式 的開發者,以及接手後續維運的資訊部門人員。文中不預設特定語言或框架。這個領域有很多術語直接沿用英文流通,所以整理在 1.1。開頭那份工作表的內容摘要放在 1.2。

1. 先講結論

說得粗略一點,但實務上好用的版本是這樣。

  • 要裝到整台機器,有服務或 COM 註冊,需要先裝前置相依,就先以 MSI 為起點來想
  • 以 Windows 10/11 為前提,想要 clean install / clean uninstall、頻繁更新、package identity,MSIX 很有力
  • 想把 .NET 的公司內部桌面應用程式以使用者為單位輕鬆散發並自動更新,ClickOnce 到現在仍然相當強
  • 若優先的是 放著就能跑的工具、封閉網路、USB 散發、不需要系統管理員權限,xcopy 最直接了當
  • 想連更新 UX、頻道、staged rollout、telemetry、復原策略都自己掌控,那就是 自訂 updater
  • 需要驅動程式 時,一開始就別以 MSIX 為中心來想比較安全
  • 需要 Explorer 的 in-process shell extension 時,先確認 MSIX 能支援的範圍與 OS 版本條件

粗略歸納起來是這樣。

  1. 向 OS 註冊的成分很濃 → 偏 MSI
  2. 想拿到 package identity 與 modern packaging → MSIX
  3. 想要 per-user 的簡易散發與 built-in 更新 → ClickOnce
  4. 放著就能用的散發是第一優先 → xcopy
  5. 有決心自行設計並維運更新平台 → 自訂 updater
5 種方式的粗略歸納說明向 OS 註冊的成分很濃就偏 MSI,想拿到 package identity 與 modern packaging 就用 MSIX,想要 per-user 的簡易散發與 built-in 更新就用 ClickOnce,放著就能用的散發是第一優先就用 xcopy,有決心自行設計並維運更新平台就用自訂 updater 的對應關係的圖。濃不濃要不要是放著就能用最優先向 OS 註冊的成分濃不濃偏 MSI要不要 package identityMSIX是不是 per-user 簡易散發+自動更新ClickOncexcopy有決心自行掌控更新平台就用自訂 updater

圖 2: 猶豫時,依註冊的濃度、identity、散發的簡易度這個順序來釐清。

1.1 本文會出現的術語

散發相關的術語有很多直接沿用英文,先在這裡列出來。

術語 中文說法 意思
package identity 套件識別 OS 給予已封裝應用程式的唯一識別。有些 Windows 功能沒有它就用不了
authoring 製作 installer 定義 MSI 內容的工作。用法接近「撰寫 MSI」
custom action 自訂動作 installer 的標準動作不夠用時,用自己的程式碼插入處理的機制
ARP 應用程式清單 Add / Remove Programs 的縮寫。指「設定」裡的「已安裝的應用程式」,或控制台「程式和功能」列出的清單
clean install / clean uninstall 乾淨的安裝 / 移除 該裝的都完整裝進去,移除時不留殘骸的狀態
repair 修復 用 installer 的機制,把壞掉的安裝狀態還原回去
telemetry 使用狀況量測 收集更新成敗與使用狀況並加以掌握的機制
per-user / per-machine 以使用者為單位 / 以電腦為單位 只裝給該使用者,還是所有使用者共用一份
shell extension 檔案總管擴充 右鍵選單、圖示顯示等,嵌進檔案總管的元件
unrestricted 不受限 不受套件的限制,以純 Win32 自由存取檔案與登錄檔的狀態
side-by-side 並存 讓多個版本同時放在同一台電腦上
staged rollout 分階段散發 不一次把新版發給所有人,而是定好比例逐步擴大

1.2 開頭的工作表裡有什麼

放在開頭的 Excel 工作表,是為了 把本文的判斷套到自己的案子上並記錄下來 而準備的。有日文版與英文版,各由 2 張工作表組成。

Planner 工作表 分成 3 個區塊。

  1. 輸入表:填完下列 7 個項目,就能把第一候選與理由留成文字
    • 散發範圍……per-user / per-machine / 兩者皆有 / 未定
    • OS 整合要素……無 / 服務 / 驅動程式 / shell extension / COM 註冊 / 多項
    • package identity……需要 / 不需要 / 無法判斷
    • 標準使用者安裝需求……必要 / 不需要 / 視條件而定
    • 更新頻率……手動或很少 / 每月 / 每週 / 更高
    • 目標環境……封閉網路或離線 / 受管理的新版 Windows / 混雜舊世代的 Windows / USB 與現場
    • 應用程式類型備註……公司內部 .NET 桌面應用 / 商用產品 / 工具程式 / 混合
  2. 候選的辨別方式:5 種方式各自的「首先要重點看的條件」與「可以先排除的條件」
  3. 判斷流程:上面的項目要照什麼順序看,結果又會偏向哪一種方式

Reference 工作表 則是把本文第 3 章的判斷表與第 4 章的比較表原樣搬過來。

換句話說,這就是把文章的第 3、4、7 章做成可以逐案填寫的形式。如果光讀就能得出結論,那不必下載。想比較多個案子、想在公司內留下判斷依據時再用。

工作表的用法說明先填完 Planner 工作表的 7 個項目,再用候選的辨別方式與判斷流程靠向某一種方式,最後把第一候選與理由寫下來,把判斷變成逐案記錄的工作表流程的圖。填完輸入表的 7 個項目用候選的辨別方式縮小範圍用判斷流程靠向某一種方式把第一候選與理由寫下來Reference 工作表是第 3、4 章的表

圖 3: 工作表是把文章的判斷,變成逐案記錄的東西。

圖中實線表示始終成立的關係,虛線表示附帶條件的關係(成立條件寫在詳細頁面中各關係的說明中)。關係的完整清單(共 17 條,附依據與可信度)以及主要概念的定義,彙整在知識地圖詳細頁面(日文)。資料:JSON-LD / Turtle

2. 這 5 種不在同一個擂台上

這一點相當重要。

MSI / MSIX / ClickOnce / xcopy 主要在談 怎麼裝進去。 而 自訂 updater 主要在談 更新責任怎麼扛。

所以在實務上,分成兩層來想會比較好梳理。

層 主要候選 要決定的事
初次安裝 MSI / MSIX / ClickOnce / xcopy 放到哪裡、要註冊什麼、權限、解除安裝
持續更新 MSIX App Installer / ClickOnce / 手動抽換 / 自訂 updater 檢查更新、發送來源、簽章驗證、rollback、頻道、UI

畫成圖是這樣。虛線代表「選了那個安裝方式,就會自然接上的更新手段」。

想散發的 Windows 應用程式首先:怎麼裝進去初次安裝層接著:更新責任由誰扛持續更新層MSIMSIXClickOncexcopyMSIX App InstallerClickOnce 的 built-in 更新手動抽換自訂 updater

圖 4: 初次安裝層與持續更新層的兩層模型。虛線是會自然接上的更新手段。

ClickOnce 與 MSIX 只要決定了上面那一層,下面那一層也差不多定了。相對地,MSI 與 xcopy 必須另外決定下面那一層。「更新要怎麼做」最容易懸在半空中的,就是選了這兩種的時候。

所以把 自訂 updater 想成不是一開始就選的東西,而是既有散發方式滿足不了更新需求時才追加選用的東西,判斷才不會晃動。

更新會懸空的是 MSI 與 xcopy說明 ClickOnce 與 MSIX 只要決定安裝方式更新手段也差不多定下來,但 MSI 與 xcopy 必須另外決定持續更新層,而自訂 updater 是在更新需求不足時才追加選用的圖。選 ClickOnce / MSIX更新手段也差不多定了選 MSI / xcopy更新要怎麼做懸在半空另外決定持續更新層不夠時再追加自訂 updater

圖 5: 自訂 updater 不是最初的選項,而是補上更新層缺口的追加選擇。

3. 一張表看完的判斷表

先放上最好用的判斷表。

情境 先選的方式 理由
對全體使用者散發,且有服務、COM 註冊、machine-wide 設定 MSI 直接站上 Windows Installer 的擂台比較不會出事
以 Windows 10/11 為前提,想要 clean install / uninstall、頻繁更新、package identity MSIX 容易靠向 modern packaging 與 update 模型
想把 .NET 的公司內部業務應用程式以 per-user 輕鬆散發 ClickOnce built-in 的更新模型很好用
放著就能跑的工具、封閉網路、USB、不需要系統管理員權限 xcopy 盡量不把 install 這個概念帶進來
商用產品,想自己掌控更新 UX 與頻道 自訂 updater 自由度比 built-in 更新高
需要驅動程式 偏向 MSI 或專用 installer driver package 是另一回事,MSIX 不適合
需要 in-process shell extension 偏向 MSI 或專用 installer Windows 11 21H2 之後可以用 MSIX 註冊 legacy context menu handler 等,但需要確認條件

這張表最重要的一點是,不要只因為「有更新需求」就跳到自訂 updater。

4. 依觀點比較

觀點 MSI MSIX ClickOnce xcopy 自訂 updater
per-user 安裝的容易度 ○ ○ ◎ ◎ ○
per-machine 安裝的容易度 ◎ ○ △ × ○
built-in 更新 △ ◎ ◎ × ◎
package identity × ◎ × × ×
與服務的契合度 ◎ △ × × ○
與驅動程式的契合度 △ × × × ○
與 shell extension 的契合度 ◎ △ × × ○
封閉網路與離線散發 ◎ ○ ○ ◎ ◎
實作與維運成本 ○ ○ ◎ ◎ ×
更新 UX 的自由度 △ ○ △ × ◎

看這張表該問的不是 哪一種最強,而是 哪一種摩擦最小。

5. 各自適合什麼樣的案子

5.1 MSI

MSI 是 想把 Windows 傳統桌面應用程式的 install / uninstall / repair 做到位 時的基準點。

特別適合的是這類案子。

  • 對全體使用者散發的業務應用程式
  • 含 Windows 服務的應用程式
  • 伴隨 COM 註冊、file association、machine-wide 設定的應用程式
  • 已經有既有 installer 維運流程的產品

MSI 的強項在於,容易用 Windows 的慣例表達「這個應用程式是怎麼裝進 OS 的」。

另一方面,弱點也很清楚。

  • authoring 不起眼卻很難
  • upgrade / patch 設計得草率,之後會很難收拾
  • custom action 加得越多越容易壞
  • 高頻率更新的產品,更新 UX 容易變得笨重
MSI 的強項與代價說明 MSI 一方面容易用 Windows 的慣例表達應用程式是怎麼裝進 OS 的,另一方面 authoring 很難,custom action 加得越多越容易壞,高頻率更新時更新 UX 也容易變笨重的圖。MSI用 Windows 的慣例表達怎麼裝進 OSinstall / uninstall / repair 一應俱全authoring 不起眼卻很難custom action 加得越多越容易壞

圖 6: MSI 換來 OS 整合的表達力,代價是 authoring 的難度。

5.2 MSIX

MSIX 是 想拿到 modern packaging 與 clean update / uninstall 的選擇。想使用需要 package identity 的 Windows 功能時,意義也很大。

適合的大致是這些。

  • 可以把 Windows 10/11 當作前提的桌面應用程式
  • 更新頻率偏高的業務應用程式
  • 想使用 package identity 才生效的 Windows 功能的應用程式
  • 想靠向 Intune 或 App Installer 的案子

MSIX 的強項是 更新與解除安裝很乾淨。

不過,並不是什麼都裝得進去。尤其下面這 4 點,一開始就先確認比較安全。

  • in-process shell extension(Windows 11 21H2 之後的 MSIX 可以註冊 legacy context menu handler 等,但需要確認資訊清單的宣告與目標 OS)
  • driver
  • 以 unrestricted 的舊式 Win32 為前提
  • 不想取得 package identity 的架構

這 4 點各自要查的資料不同。不要停在「聽說 MSIX 不行」,先決定好看哪份資料才能拍板,會快很多。

想確認的事 要看的資料 能查到什麼
從哪個 Windows 版本開始可以用 Microsoft Learn 的「MSIX features and supported platforms」 各項功能支援的 OS 版本整理成表
能不能註冊 in-process shell extension Microsoft Learn 的「Support legacy context menus for packaged apps」 支援的 OS 版本,以及在資訊清單裡的宣告方式
自己的 installer 能不能轉成 MSIX Microsoft Learn 的「Prepare to package a desktop application」與「Know your installer」 無法封裝的架構清單,以及事前該確認的點
含服務的架構會變成怎樣 Microsoft Learn 的「Convert an installer that includes services」 含服務的轉換條件與限制

這些都在第 9 章的參考資料裡放了連結。判斷時要看到的 不是「有沒有支援」,而是「從哪個版本起、要怎麼宣告才會支援」。這裡沒有連 OS 版本條件一起弄清楚,之後就會以「驗證機上跑得動,現場的舊版 Windows 卻裝不進去」的形式冒出來。

MSIX 的限制要連查證來源一起決定說明 shell extension 與 driver 等 MSIX 上讓人猶豫的 4 點各自要查的資料不同,因此不要停在聽說不行,而要看到從哪個版本起、要怎麼宣告才會支援,藉此避免驗證機能跑而現場裝不進去的事故的圖。MSIX 上讓人猶豫的 4 點不要停在「聽說不行」決定用哪份資料拍板看到從哪一版起、用什麼宣告才支援避免驗證機 OK、現場 NG

圖 7: MSIX 的限制要查到 OS 版本條件與宣告方式才算拍板。

5.3 ClickOnce

ClickOnce 在 想把 .NET 的公司內部桌面應用程式以 per-user 快速散發,並連更新一起運轉 時,到現在仍然相當強。

適合的是這些場面。

  • 公司內部的業務應用程式
  • 想以標準使用者身分安裝
  • 以使用者為單位散發就夠了
  • 不想把更新 UX 做得太細

反過來說,會深入碰 OS 的產品,或是要把多個前置相依綁在一起的 installer 角色,別期待它做到比較安全。

5.4 xcopy

xcopy 是 deploy 而不是 install。沒有登錄檔註冊,沒有修復功能,也沒有 package identity。相對地,只要 放著就能結束,它單純到近乎無敵。

能發揮特色的是這類工具。

  • 診斷工具
  • 設備設定工具
  • 日誌收集工具
  • 用 USB 送到現場的工具程式
  • 想以 side-by-side 讓多個版本並存的情況

xcopy 的強項是 失敗的方式很好懂。整個資料夾抽換,想退回就退回前一版,這樣的維運方式很好做。

xcopy 是 deploy 而不是 install說明 xcopy 不具備登錄檔註冊、修復功能與 package identity,換來的是放著就能結束,整個資料夾抽換、想退回就退回前一版,這種失敗方式很好懂的維運的圖。整個資料夾放上去就這樣跑起來更新就是整個資料夾抽換要退回就退回前一版沒有註冊、修復、identity

圖 8: xcopy 的價值在於安裝、更新、退版都很單純。

當然,弱的地方也有。

  • Start menu / ARP / repair
  • file association / service / shell extension / driver
  • built-in 更新

5.5 自訂 updater

自訂 updater 與其說是 自由度的選擇,不如說是 責任的選擇。

值得考慮的,是有這些需求的時候。

  • 更新頻率高
  • 想要 stable / beta / preview 這類頻道
  • 想控制 staged rollout 與推出比例
  • 想細緻控制背景下載、通知、維護時段
  • 想自己掌握更新 telemetry 與 crash recovery

強項很大,但要付出的也很大。

  • 簽章驗證
  • 發送用的 manifest
  • 重試 / resume
  • proxy / firewall / 封閉網路的因應
  • rollback
  • 壞掉的更新的復原
  • updater 本身的更新

也就是說,增加的不是自由度,而是責任。

自訂 updater 是責任的選擇說明自訂 updater 換到頻道、staged rollout、telemetry 這類自由度的同時,也要自行設計並維運簽章驗證、發送用 manifest、rollback、壞掉的更新的復原,乃至 updater 本身的更新的責任的圖。得到的:頻道、staged rollout、telemetry自訂 updater付出的:簽章驗證、rollback、復原增加的不是自由度,而是責任updater 本身的更新也是自己的工作

圖 9: 自訂 updater 增加的不是自由度,而是更新平台的維運責任。

5.6 決定方式之後,接下來要查什麼

就算決定「走 MSI」,接下來不知道該查什麼,一樣會卡住。這裡列出幾個代表性的入口。它們都不是「就用這個」,而是 選了那個方式的話,先知道名字會比較好的東西。

決定的方式 接下來要查的東西 補充
MSI WiX Toolset 用 XML 撰寫 MSI 的開放原始碼工具集。是 MSI authoring 的標準入口
MSI Advanced Installer、InstallShield 以 GUI 為主的商用 MSI 製作工具。想用 GUI 組出 custom action 與 upgrade 設計時
不需要 MSI,EXE 格式即可 Inno Setup、NSIS 做出來的不是 MSI,而是自有格式的 EXE installer。不會站上 Windows Installer 的擂台
MSIX MSIX Packaging Tool、makeappx.exe、signtool.exe 從既有 installer 轉換的工具,以及 Windows SDK 的封裝與簽署工具
MSIX Windows Application Packaging Project 在 Visual Studio 這一側把既有專案轉成 MSIX 的專案類型
ClickOnce Visual Studio 的發行精靈、mage.exe 發行與產生 manifest。更新的行為由發行時的選項決定
自訂 updater Squirrel.Windows、Velopack、WinSparkle、NetSparkle 會替你準備好更新骨架的函式庫。比起要不要採用,請先用 簽章驗證與 rollback 怎麼處理 來比較

這裡要注意的是,選工具和選方式是兩回事。例如 Inno Setup 很好上手,但做出來的不是 MSI,所以以 Windows Installer 為前提的維運,例如用群組原則散發軟體,或用 msiexec 修復,都接不上。如果 5.1 選 MSI 的理由正在那裡,工具也必須配合。

選工具和選方式是兩回事說明 Inno Setup 雖然好上手,但做出來的不是 MSI,因此接不上群組原則的軟體散發與 msiexec 的修復,必須依照選擇方式的理由來配合選工具的圖。決定方式決定工具Inno Setup 不會做出 MSI接不上 GPO 散發與 msiexec 修復讓工具配合選擇方式的理由

圖 10: 好用的工具,不一定站得上你選的那個方式的擂台。

6. 容易猶豫的幾個論點

6.1 是否需要 package identity

如果想要的是以 package identity 為前提的 Windows 功能,MSIX 的價值會一口氣上升。

反過來,若要的是:

  • unrestricted 的 file system access
  • unrestricted 的 registry access
  • elevation / process model 的自由度
  • 想原封不動保留舊的 Win32 前提

那麼偏 unpackaged 的方式比較自然。

以是否需要 package identity 來分說明想要以 package identity 為前提的 Windows 功能時 MSIX 的價值會一口氣上升,而想要 unrestricted 地存取檔案與登錄檔、想原封不動保留舊的 Win32 前提時,偏 unpackaged 的方式比較自然的圖。要想 unrestricted 地跑要不要以 package identity 為前提的功能MSIX 的價值一口氣上升偏 unpackaged 的方式比較自然

圖 11: 是否需要 identity,是 packaged 與 unpackaged 的分水嶺。

6.2 是否有服務 / 驅動程式 / shell extension

這 3 個會讓散發方式一口氣變重。

  • driver:MSIX 不適合
  • in-process shell extension:MSIX 不適合
  • Windows service:MSI 很自然,MSIX 也能有條件地納入比較

與 OS 綁得越深的要素越多,主題就越不是 看起來簡單的散發,而是 能不能正確地安裝、更新、移除。

6.3 per-user 還是 per-machine

這裡含糊帶過就往前推,之後一定會吵起來。

  • 想偏 per-user
    • ClickOnce
    • xcopy
    • 部分的 MSIX
  • 想偏 per-machine
    • MSI
    • 條件符合的話 MSIX

「想在沒有系統管理員權限的情況下安裝」和「想讓所有使用者從同一個位置使用」不是同一件事。

不要混淆 per-user 與 per-machine說明想偏 per-user 時候選是 ClickOnce、xcopy 或部分的 MSIX,想偏 per-machine 時候選是 MSI 或條件符合的 MSIX,而想在沒有系統管理員權限下安裝,和想讓所有使用者從同一個位置使用不是同一件事的圖。想偏 per-userClickOnce / xcopy / 部分的 MSIX想偏 per-machineMSI / 條件符合的話 MSIX免權限安裝與全員共用位置是兩回事

圖 12: 安裝範圍含糊帶過就往前推,之後一定會吵起來。

6.4 更新頻率與維運責任

從更新頻率的感覺來看,大致是這樣。

  • 每季到每月更新:MSI 也足以應付
  • 每月到每週更新:MSIX / ClickOnce 會輕鬆很多
  • 每週到每日更新:開始有理由考慮自訂 updater
  • 更新用手動就好 / 由部署那一側控制:xcopy 也夠用

散發方式既是 技術選型,同時也是 維運設計。

更新頻率的階梯說明每季到每月更新時 MSI 也足以應付,每月到每週時 MSIX 或 ClickOnce 會輕鬆很多,每週到每日時會出現考慮自訂 updater 的理由,更新用手動就好時 xcopy 也夠用這樣的更新頻率參考值的圖。每季~每月:MSI 也夠用每月~每週:MSIX / ClickOnce 輕鬆每週~每日:出現考慮自訂 updater 的理由手動就好的話 xcopy 也夠用

圖 13: 更新頻率越高,built-in 更新或自建平台的價值就越大。

6.5 封閉網路與離線散發

在封閉網路裡,單純 往往勝過漂亮的 auto-update。

  • xcopy 很強
  • MSI 也很強
  • ClickOnce 也能走 file share 或 removable media
  • MSIX 只要 App Installer 用得對也能運轉

不過在封閉網路裡要頻繁更新,就得連「誰、把新版放到哪、舊版怎麼保留」都決定好,否則光選了方式,維運還是很容易亂掉。

封閉網路裡單純會勝出說明封閉網路裡單純往往勝過漂亮的 auto-update,而要頻繁更新時若不連誰、把新版放到哪、舊版怎麼保留都決定好,光選了方式維運還是很容易亂掉的圖。封閉網路與離線環境比起漂亮的 auto-update 更要單純xcopy 與 MSI 很強連誰、把新版放到哪都決定好舊版怎麼保留也要決定

圖 14: 封閉網路裡,比選方式更早要決定的是新版與舊版的擺放維運。

7. 猶豫時最後要看的 6 個問題

  1. 這個應用程式只要 current user 就好,還是必須裝成 machine-wide
  2. 有沒有 service / driver / shell extension / COM 註冊
  3. 會不會用到需要 package identity 的 Windows 功能
  4. 是不是想只用標準使用者權限安裝
  5. 更新頻率是每月、每週,還是更高
  6. 目標環境是不是封閉網路,OS 版本齊不齊

只要回答這 6 題,大致就能看見落點。

  • 2 是「有」 → 先從 MSI 這一側想
  • 3 是「會」 → 優先考慮 MSIX
  • 1 是 current user、4 是「是」,而且是 .NET desktop app → ClickOnce 很有力
  • 4 是「是」、2 是「沒有」,而且放著就能維運 → xcopy 很有力
  • 5 很高,而且想把更新 UX 當成產品價值來掌控 → 把自訂 updater 放進比較對象
從 6 個問題得到的落點說明有服務等 OS 整合就先從 MSI 這一側想,需要 package identity 就優先考慮 MSIX,current user 且以標準使用者安裝的 .NET 桌面應用程式就選 ClickOnce,放著就能維運就選 xcopy,更新頻率高且想掌控更新 UX 就把自訂 updater 放進比較對象的落點的圖。有沒有需要不需要若是 .NET 桌面應用程式若是放著就能維運有沒有 OS 整合(服務等)先從 MSI 這一側想需不需要 package identity優先考慮 MSIX是不是 per-user+標準使用者安裝ClickOnce 很有力xcopy 很有力想掌控更新 UX 就也把自訂 updater 納入比較

圖 15: 照這個順序追這 6 題的答案,落點大致就看得見。

8. 總結

Windows 應用程式的散發方式,大致可以濃縮成下面這一句。

初次安裝要怎麼成立,和 持續更新由誰負責運轉,這兩件事要分開決定。

在此之上,粗略的實務判斷是這樣。

  • MSI:深入裝進 OS 的傳統 desktop app
  • MSIX:想拿到 package identity 與 modern packaging / update 的 app
  • ClickOnce:想把 per-user 的 .NET 業務應用程式輕鬆散發並更新
  • xcopy:放著就好、自成一體的工具
  • 自訂 updater:有決心自行設計並維運更新本身的產品

而最重要的是這幾點。

  • 有 driver / shell extension / service 時,散發方式不是最後的外觀,而是由 OS 整合的方式決定
  • 需要 package identity 時,MSIX 的意義就很大
  • 自訂 updater 是最後的王牌,不是最初的選項
  • 在 封閉網路 裡,單純往往勝過聰明

如果還在猶豫,先把 per-user 還是 per-machine、要向 OS 註冊什麼、更新頻率大概多高 這 3 件事固定下來,討論就能明顯往前推進。

先固定下來的 3 件事說明還在猶豫時,先把 per-user 還是 per-machine、要向 OS 註冊什麼、更新頻率大概多高這 3 件事固定下來,散發方式的討論就會往前推進不少的圖。per-user 還是 per-machine先固定下來要向 OS 註冊什麼更新頻率大概多高討論會往前推進不少

圖 16: 方式拿不定主意時,至少先把這 3 點固定下來。

9. 參考資料

共用相同標籤的最新文章。能以相近的主題延伸理解。

與本文相近的主題頁面。以本文為起點,可進一步連到相關服務與其他文章。

本文連結到以下服務頁面,歡迎從最接近的入口查看。

常見問題

整理諮詢這個主題時常見的問題。

MSI 與 MSIX 的差別是什麼?
MSI 是 Windows 傳統的 installer 格式,與 per-machine 安裝、Windows 服務、COM 註冊、shell extension 這類會深入碰 OS 的安裝很合,而且能用 Windows 的慣例表達 install / uninstall / repair。MSIX 則是以 Windows 10/11 為前提的 modern packaging,強項在 clean install / clean uninstall、頻繁更新與 package identity。另一方面,MSIX 不適合驅動程式,in-process shell extension 要到 Windows 11 21H2 之後才有條件支援,也不適合以 unrestricted 的舊式 Win32 為前提的架構。向 OS 註冊的成分很濃就從 MSI 起算,想要 package identity 與乾淨的更新就從 MSIX 起算。
MSIX 與 ClickOnce 該選哪一個?
想把 per-user 的 .NET 公司內部業務應用程式輕鬆散發並自動更新,ClickOnce 到現在仍然是相當強的選擇。它 built-in 的更新模型很好用,能以標準使用者身分安裝,也不必自己把更新 UX 做出來。另一方面,想使用需要 package identity 的 Windows 功能、重視 clean install / uninstall、想靠向 Intune 或 App Installer 時,MSIX 就很有力。兩者都不適合會深入碰 OS 的產品,所以有服務或驅動程式時要從 MSI 這一側開始想。
ClickOnce 現在還能用嗎?是不是已經過時的技術?
現在還能用,而且在合適的場面上是相當強的選項。想把 .NET 的公司內部桌面應用程式以使用者為單位(per-user)、維持標準使用者權限快速散發,並以 built-in 的更新模型運轉時,它很有效。反過來說,Windows 服務、驅動程式、shell extension 這類會深入碰 OS 的產品,或是要把多個前置相依綁在一起的 installer 角色,最好別期待它做到。以更新頻率來看,每月到每週左右的更新,用 ClickOnce 或 MSIX 都能相當輕鬆地運轉。
什麼時候該考慮自訂 updater?
自訂 updater 不是一開始就選的東西,而是既有散發方式滿足不了更新需求時,才追加選用的東西。值得考慮的時機是:更新頻率高、想要 stable / beta / preview 這類頻道、想控制 staged rollout 與推出比例、想自己掌握更新 telemetry 與 crash recovery。不過,簽章驗證、發送用的 manifest、重試、rollback、壞掉的更新的復原,乃至 updater 本身的更新,都要由自己設計並扛起維運責任,所以應該把它想成增加的不是自由度,而是責任。

作者檔案

本文作者的個人檔案頁面。

Go Komura

小村軟體有限公司 代表

以 Windows 軟體開發、技術諮詢與故障調查為中心,在難以重現的故障調查與既有資產仍在運作的專案上具有優勢。

回到部落格一覽