per-machine な Windows アプリはどうやって静かに自動更新しているのか — Chrome・Slack・VS Code の実装から学ぶ 3 大パターン
2025 年、Slack は Windows 向けの machine-wide MSI インストーラを退役させ、per-user インストーラと MSIX に一本化しました(Slack Help Center: Download Slack for Windows の現行案内から MSI の記載が消えている点、および Slack のダウンロードページから MSI 配布リンクが撤去されている点で確認できます)。長年 IT 部門が SCCM や Intune で配ってきたあの .msi が消えたということです。
per-user インストール(ユーザーごとに %LocalAppData% に入るタイプ)なら、自動更新はそこまで難しくありません。書き込み先も実行権限も全部そのユーザーの範囲で完結します。per-machine(C:\Program Files に入るタイプ)では、更新先への書き込み権限が問題になります。標準ユーザーには Program Files への書き込み権限がなく、しかも企業環境の従業員には admin を渡さない、というのが今の日本企業ではむしろ普通だからです。
Slack がなぜあのタイミングで MSI をやめたのか、Chrome や Edge や Docker Desktop がどうやって静かに更新しているのかは、この「per-machine × silent auto-update × 標準ユーザー」の三重苦をどう成立させるかという設計問題に集約されます。本記事では実在アプリの実装を先に並べ、そこから 3 つのパターンに帰納します。
前提: per-machine と per-user は保存先と更新権限が異なる
まず用語をそろえます。Windows デスクトップアプリのインストール方式は、大きく per-machine と per-user に分かれます。
| 観点 | per-machine | per-user |
|---|---|---|
| インストール先 | C:\Program Files / Program Files (x86) | %LocalAppData%\Programs など |
| レジストリ | HKLM\Software\... | HKCU\Software\... |
| インストール時に必要な権限 | admin(UAC 昇格) | 標準ユーザーで可 |
| 更新時に必要な権限 | admin(そのままでは UAC) | 標準ユーザーで可 |
| 対象ユーザー | そのマシンの全ユーザー | インストールしたユーザーのみ |
per-machine は 1 台のマシンに 1 セットのバイナリだけを置き、全ユーザーに共有します。企業配布や IT 統制と相性が良い一方、更新時に書き込むファイルが Program Files 配下にあるため、UAC(User Account Control) が admin 権限を要求します。標準ユーザーが admin を持たない世界では、単純に「アプリ自身が自分を上書きする」という素朴な自動更新は成立しません。
per-user はこの制約から解放されます。実行ユーザーの %LocalAppData% は本人が自由に書き換えられるので、UAC を出さずに静かに置き換えられます。Slack・Discord・Visual Studio Code(User Setup)・Zoom(クライアント版)などがこの方式を採る主な理由はここにあります。
つまり、per-machine で silent auto-update をやりたいというのは、「標準ユーザーには不可能なはずの操作を、しかし UAC を一切出さずに実行したい」という要求です。この要求を成立させる典型的な解が、これから見ていく 3 つのパターンです。
パターン A: Omaha 型 SYSTEM サービス
最初のパターンは、更新処理を Windows サービスとして SYSTEM 権限で常駐させる方式です。アプリ本体は標準ユーザー権限で動きますが、更新は別プロセスの SYSTEM サービスに丸投げします。SYSTEM はそもそも Program Files に書けるので、UAC は出ません。
採用例
代表格は Google Chrome の Omaha(Chromium Updater) です。Chrome のインストール後、Windows には GoogleUpdate 系のサービスと Scheduled Task が仕込まれ、これがバックグラウンドで更新チェックとダウンロード・差し替えを行います。Omaha は OSS 化されており、chromium/src/chrome/updater にコードがあります。
同じ発想を継承した実装は多数あります。
- Microsoft Edge は Omaha フォークベースの
MicrosoftEdgeUpdateサービスを使う(Microsoft Edge Update policies documentation 参照) - Adobe Creative Cloud は
Adobe Genuine Service(AGS)や Creative Cloud Desktop の常駐サービスで更新を配る - Dropbox は
DropboxUpdate系サービスを持ち、Chrome とよく似た周期でチェックする - Zoom の企業配布向け MSI は Automatic Update を有効にすると
ZoomAutoUpdaterサービス経由で silent 更新できる - Docker Desktop も近年のバージョンで silent component updates を GA し、
com.docker.serviceを使って標準ユーザーでも UAC なしで更新できるようになった(Docker Desktop release notes 参照)
Docker Desktop がここ数年でようやく silent update に到達したのは、この方式の実装が大手ですら簡単ではないことの傍証です。Windows サービスを書き、権限境界を設計し、破損時のリカバリと差分適用と署名検証を実装する、という工程は本気で作ると 1 プロダクトぶんの規模になります。
仕組みの骨格
3 つのパーツで構成されます。
- インストール時に Windows Service を SYSTEM 権限で登録する
- Scheduled Task が定期的にサービスを起こし、バージョンチェック用のサーバに問い合わせる
- 新バージョンが見つかったら SYSTEM 権限で
Program Files配下のバイナリを差し替える
Chrome の場合、この定期タスクは Windows Task Scheduler から 1 時間おきに起動され、最短 5 時間間隔で更新チェックを行うようスロットルされます(企業ポリシーで調整可能。Chromium Updater の設計ドキュメント に基本設計が公開されています)。ユーザーが Chrome を閉じている間でも更新は進むので、体感としては「次回の起動時には自動更新が完了していた」となります。
メリットとデメリット
メリットは 4 つあります。第一に、アプリを開いていなくても更新できる。第二に、UAC が出ないので企業ユーザー体験を壊さない。第三に、更新失敗時のロールバックを SYSTEM 側で丁寧に組める。第四に、更新チャネル(stable・beta・dev)や強制インストールバージョンなど、企業向けのポリシー制御を細かく効かせられる。
デメリットは実装コストです。Windows Service の設計・署名済みインストーラ・破損リカバリ・複数世代の並行運用・A/B ロールアウトまで真面目に作ると、多くのチームでは現実的でありません。Chromium Updater が OSS 化されてもなお、Chrome 以外の採用が広がりきらないのはこの重さに理由があります。
パターン B: MSIX(プラットフォーム委譲)
2 つ目のパターンは、更新機構を自分で書かず、Windows 自身に任せる方式です。MSIX パッケージとして配布し、.appinstaller XML で更新元と更新頻度を宣言しておくと、Windows の App Installer サービスがバックグラウンドで更新を担当します。アプリ側は基本的に「新しい MSIX を置いておく」だけで済みます。
採用例
- Slack は 2025 年に MSI を段階的に廃止し、per-user インストーラと MSIX に一本化した(Slack Help Center: Download Slack for Windows 参照)
- Microsoft Teams の新クライアントは MSIX ベースで、Windows App SDK 系の仕組みに乗る
- 1Password は Microsoft Store 版で MSIX 配布を採る
- Docker Desktop も Microsoft Store 経由での MSIX 配布経路を持つ
Slack が MSI をやめた理由は、単純化すれば「per-machine 配布と silent 更新を両立させたかったが、独自の SYSTEM サービスを書くほどの体力を Slack Desktop に張り続けるのは割に合わない」という判断だと読めます。MSIX に載れば、更新機構を丸ごと OS 側に委譲できます。
仕組みの骨格
.msix(または.appx)にアプリを固めるPublisherを EV コード署名で固定し、Windows がパッケージ同一性を厳密に確認できるようにする.appinstallerXML にHoursBetweenUpdateChecksなどを書き、Windows App Installer に更新のトリガーを渡す- 企業配布では sideload 用証明書を Intune や SCCM 経由で先に配っておく
.appinstaller の最小例を挙げると次のようになります。
<AppInstaller Uri="https://cdn.example.com/app.appinstaller"
Version="1.2.3.0"
xmlns="http://schemas.microsoft.com/appx/appinstaller/2018">
<MainPackage Name="Example.App"
Publisher="CN=Example, O=Example, C=JP"
Version="1.2.3.0"
Uri="https://cdn.example.com/app.msix" />
<UpdateSettings>
<OnLaunch HoursBetweenUpdateChecks="8" />
<AutomaticBackgroundTask />
</UpdateSettings>
</AppInstaller>更新には Publisher の CN が完全に一致する必要があります。証明書更新やベンダー名変更でここがずれると、Windows 側は「別パッケージ」と見なして更新を拒否します。
Electron 系では electron-windows-msix や、Electron Forge の MSIX Maker を使うと、既存の Electron ビルドから MSIX を組み立てられます。Microsoft Learn の MSIX packaging overview と Windows デスクトップアプリのモダナイズ も参考になります。
メリットとデメリット
メリットは、更新機構をゼロから書かずに済む点、per-machine と per-user の両方に対応できる点、そして Store 配布も同じパッケージで通せる点です。企業配布の観点では、MSIX は Intune の「Windows アプリ (Win32)」や「Line-of-business アプリ」経路と自然に馴染みます。
デメリットは 3 つあります。第一に、Publisher CN 一致・sideload 証明書の事前配布・コンテナ化された実行環境 といった MSIX 固有の制約が、既存 Win32 前提の実装(管理者権限を暗黙に前提としていた処理、任意パス書き込みなど)と衝突しやすい。第二に、ネイティブサービスや低レイヤーのフック(アンチウイルスやシステム統合系)は素直に載らない。第三に、ロールアウトの細かい制御は Omaha 系ほど自由には効かない。
パターン C: MDM 再配布(自動更新しない)
3 つ目は、そもそもアプリ自身に自動更新を持たせず、更新のたびに IT 部門が MDM(Microsoft Intune・SCCM・SKYSEA Client View など)から再配布する方式です。統制の観点ではもっとも素直で、日本企業の情シス運用と最も相性が良いパターンでもあります。
採用例
- Notepad++ は per-machine 配置で WinGUp を使い、15 日ごとに新版の有無を確認して通知するが、実際の適用は
Program Filesへの書き込みを伴うため管理者権限のインストーラ実行に落ちる - Visual Studio Code の System Installer は「System Setup は自動更新しない、個人利用なら User Setup を推奨」と VS Code 公式が明記している
- 1Password の MSI 版 は
MANAGED_UPDATE=1で自動更新を無効化し、IT が MDM から新バージョンを配る運用を公式に想定 - 旧 Slack MSI(2025 年に退役)はまさにこの運用の代表格だった
VS Code の Windows Setup ドキュメント は System Setup について「This setup requires administrator permissions and installs under Program Files. In-product updates also require elevation.」と明記しており、更新のたびに管理者権限が要る(つまり silent auto-update を構造的に諦めている)ことを認めています。Notepad++ の Upgrading ドキュメント は per-machine 配置の Notepad++ を WinGUp が 15 日周期でチェックする仕様を説明しており、Program Files に書き込む以上、更新時に管理者権限が要求されるという構造的制約から逃れられません。
仕組み
- インストーラ自体は per-machine の MSI・EXE
- アプリ内の自動更新は無効化しておく(
MANAGED_UPDATE=1などの MSI プロパティ、ポリシーレジストリなど) - 新バージョンが出たら IT 部門が MDM のアプリカタログを更新し、対象端末に再配布する
メリットとデメリット
メリットは実装コストの低さと統制の強さです。開発チームは「自動更新の面倒を IT に押しつける代わりにインストーラだけ供給する」という割り切りができ、IT 側もいつ・どのバージョンが配られるかを完全にコントロールできます。特定バージョンで検証を止めたい規制業種や、Windows 11 / 10 が混在する社内などでは合理的な選択です。
デメリットは即応性です。ゼロデイパッチが出ても、IT のリリースサイクルが月次であれば数週間の遅延が発生します。エンドユーザー体験の観点でも、「自分では新しくできない」ことに対する納得感が要ります。この方式は、自動更新機構を「実装しない」という設計判断の代わりに、「IT 運用側の負荷」を上げているだけとも言えます。トレードオフの本質はそこにあります。
例外パターン: Steam の ACL 開放
正攻法から外れた例として、Steam の挙動があります。Steam は per-machine で C:\Program Files (x86)\Steam にインストールされますが、そのインストール時にインストールフォルダの ACL を Users グループに write 相当で開放します。つまり標準ユーザーがそのままアプリ配下を書き換えられる状態にし、自動更新を成立させています。
この設計は機能としては動いてしまっていますが、Program Files 配下を書き込み可能にすることは「実行ファイルが標準ユーザー権限で置き換えられる」ことを意味し、マルウェアの永続化や権限昇格の攻撃面 を広げる、というのが一般的な評価です。少なくとも企業配布のアプリで再現すべき手法ではありません。「動いてしまっている」ことと「推奨できる」ことは別、という好例として挙げるにとどめます。
どのパターンを選ぶか
ここまで並べた 3 パターンを、実装コスト・更新即応性・IT 部門負荷・エンドユーザー体験・統制の強さの 5 軸で並べると次のようになります。
| 観点 | A: Omaha 型サービス | B: MSIX 委譲 | C: MDM 再配布 |
|---|---|---|---|
| 実装コスト | 極大 | 中 | 小 |
| 更新即応性(新版が届く速さ) | 高 | 中〜高 | 低 |
| IT 部門の運用負荷 | 低 | 低〜中 | 高 |
| エンドユーザー体験 | 高(自動更新) | 高(自動更新) | 中(IT の配布を待つ) |
| バージョン統制の強さ | 中(ポリシーで縛れる) | 中〜高(Store・sideload 統制) | 高(IT が完全に握る) |
決定の入り口は 4 つの問いに整理できます。
flowchart TD
Q1{エンドユーザーは admin 権限を持つか}
Q1 -- Yes --> P_ALL[A・B・C いずれも可]
Q1 -- No --> Q2{更新頻度は週次以上か}
Q2 -- Yes --> Q3{MSIX 化に数エンジニア週を割けるか}
Q3 -- Yes --> B[パターン B: MSIX]
Q3 -- No --> Q4{Windows Service を書ける体制か}
Q4 -- Yes --> A[パターン A: Omaha 型]
Q4 -- No --> R[per-user 化を先に検討]
Q2 -- No --> C[パターン C: MDM 再配布]
ここで意図的に選択肢に入れているのが「per-user 化」です。Slack、Discord、VS Code User Setup、Zoom クライアント(個人版)が per-user を採るのは、per-machine + silent auto-update の難しさを回避する構造的な解だからです。企業ポリシー上どうしても per-machine が要る、という制約から解いていくと、逆に per-user で済ませられる要件は per-user に寄せたほうが総コストが下がる、という結論になりやすくなります。
まとめ
Windows デスクトップアプリの per-machine × silent auto-update は、標準ユーザーに admin を渡さない企業環境と真正面から衝突する要求です。この矛盾を実際に成立させている実装は、大きく 3 パターンに帰納できます。
- パターン A: Omaha 型 SYSTEM サービスは、Chrome や Edge のような大手インフラアプリの本流ですが、実装コストは極大です。Docker Desktop がここ数年でようやく silent update に届いたことが、その難易度を物語っています。
- パターン B: MSIX プラットフォーム委譲は、2025 年以降 Electron 系エンタープライズアプリの主流になりつつあります。Slack が 2025 年に MSI をやめて MSIX に一本化した意思決定は、この流れを象徴しています。
- パターン C: MDM 再配布は、統制重視の企業配布で今なお現役です。VS Code System Installer や Notepad++、旧 Slack MSI の運用スタイルであり、Intune や SKYSEA を前提とする日本企業の情シス運用と相性が良い方式です。
Slack が MSI をやめた意思決定は、「per-machine の Windows アプリで、自前の SYSTEM サービスも書かず、しかし silent auto-update は諦めない」という要求に対する現実的な回答が、業界レベルで MSIX に寄ってきていることを示唆します。とはいえパターン C の合理性は消えていません。自社アプリの更新頻度と、配布先の IT 統制の強さの二次元で、A・B・C・per-user 化の 4 択のどこに落とすかを設計する、というのがこれからの実務上の分岐点だと思います。
以上、Chrome・Slack・VS Code の実装を並べて per-machine × silent auto-update の 3 大パターンを整理した、現場からお送りしました。
参考情報
- Chromium Updater documentation
- Microsoft Edge Update policies documentation
- Zoom Automatic Update policies
- Docker Desktop release notes
- 1Password: Deploy 1Password with MDM
- Slack Help Center: Download Slack for Windows
- Notepad++ User Manual: Upgrading
- Visual Studio Code: Setup on Windows
- Squirrel.Windows: Machine-Wide Installs
- Microsoft Learn: Windows デスクトップアプリのモダナイズ
- electron-windows-msix (GitHub)