アプリを配布したあと、「ユーザーが古いバージョンのまま使い続けている」 という問題に必ずぶつかります。バグを直してもリリースしても、届かなければ意味がありません。そこで欲しくなるのが 自動更新 です。
ただ、WinUI(C#)デスクトップアプリの自動更新は 「どう配布しているか」で手段が変わります。この記事では、代表的な3つの方法を仕組み・コード・向き不向きで比較し、自分のアプリならどれを選ぶべきか を判断できるように整理します。配布そのものの全体像は WinUIアプリのMSIXパッケージングと署名・配布 を先に読むと理解が早いです。
Table of contents
Open Table of contents
大前提:配布方法で自動更新の手段が決まる
自動更新は「後から好きに足せる機能」ではなく、配布形態とセットで考えるものです。まず全体像を押さえます。
| 配布方法 | 主な自動更新の手段 | 実装コスト |
|---|---|---|
| Microsoft Store | Store に任せる(ほぼ自動) | ほぼ不要 |
| MSIX を自社サイトで配布 | App Installer(.appinstaller) | 低〜中 |
| ポータブル版(ZIP / 従来の exe) | Velopack などの更新フレームワーク | 中 |
順に見ていきます。
方法A:Microsoft Store に任せる(いちばん楽)
ストア配信するなら、更新は Store が自動で面倒を見てくれます。新しいバージョンを提出して審査に通れば、ユーザーの端末にバックグラウンドで配信されます。アプリ側の更新実装は基本的に不要です。
- メリット:実装ゼロに近い。署名やインフラも Store 側。信頼性が高い
- デメリット:審査がある、配信の細かい制御はしにくい、ストアに載せたくないアプリには使えない
「とにかく楽に確実に更新したい」なら第一候補です。
方法B:MSIX + App Installer(ストア外で自動更新)
ストアを使わず自社サイトやストレージから配布しつつ自動更新したい場合の定番が App Installer です。.appinstaller という XML ファイルを HTTPS 上に置き、そこにパッケージの場所と更新設定を書きます。
この .appinstaller は通常 Visual Studio(パッケージ化プロジェクト)が生成しますが、中身はこんなイメージです。
<?xml version="1.0" encoding="utf-8"?>
<AppInstaller
xmlns="http://schemas.microsoft.com/appx/appinstaller/2017/2"
xmlns:s3="http://schemas.microsoft.com/appx/appinstaller/2018"
Version="1.0.1.0"
Uri="https://example.com/app/MyApp.appinstaller">
<MainPackage
Name="MyApp"
Publisher="CN=YourName"
Version="1.0.1.0"
Uri="https://example.com/app/MyApp_1.0.1.0.msix"
ProcessorArchitecture="x64" />
<UpdateSettings>
<OnLaunch HoursBetweenUpdateChecks="12" />
<s3:AutomaticBackgroundTask />
</UpdateSettings>
</AppInstaller>
Versionを上げて新しい.msixを差し替える → ユーザーは次回起動時などに自動で更新されるOnLaunchのHoursBetweenUpdateChecksで確認頻度(既定は24時間)を指定AutomaticBackgroundTaskはユーザーの起動と無関係に8時間ごとにバックグラウンド確認する設定。バージョン付き名前空間(s3/s4)が必要な点に注意
アプリから明示的に更新を確認することもできます。ここに ハマりどころ があります。Package.Current に直接 CheckUpdateAvailabilityAsync() を呼ぶと「アクセス拒否」で失敗するため、PackageManager 経由で自分のパッケージを取得してから呼びます。
using Windows.ApplicationModel;
using Windows.Management.Deployment;
// Package.Current に直接呼ぶと失敗する。PackageManager 経由で取得する
var pm = new PackageManager();
var current = pm.FindPackageForUser(string.Empty, Package.Current.Id.FullName);
var result = await current.CheckUpdateAvailabilityAsync();
if (result.Availability == PackageUpdateAvailability.Available ||
result.Availability == PackageUpdateAvailability.Required)
{
// 更新あり。ユーザーに通知する、など
}
- メリット:ストア不要で自動更新できる。MSIX なのでクリーンなインストール/アンインストール
- デメリット:コードサイニング証明書での署名が必須(未署名だとインストールで弾かれる)、HTTPS配布環境が必要
- 署名と SmartScreen 対策は MSIX配布の記事 を参照
方法C:Velopack(非MSIX・ポータブル配布向け)
「MSIX ではなく、従来どおり exe / ZIP で軽く配りたい」場合は、更新フレームワークの Velopack(Squirrel の後継)が扱いやすいです。インストーラー作成と差分更新をまとめて面倒を見てくれます。
まず起動時に Velopack のフックを通します。
using Velopack;
public static void Main(string[] args)
{
// インストール/更新時のフック処理。必ず最初に呼ぶ
VelopackApp.Build().Run();
// 通常のアプリ起動処理へ
}
更新チェックは UpdateManager で行います。
using Velopack;
using Velopack.Sources;
private static async Task UpdateMyAppAsync()
{
var mgr = new UpdateManager(
new GithubSource("https://github.com/you/your-repo", null, false));
var newVersion = await mgr.CheckForUpdatesAsync();
if (newVersion is null) return; // 最新なので何もしない
await mgr.DownloadUpdatesAsync(newVersion);
mgr.ApplyUpdatesAndRestart(newVersion); // 適用して再起動
}
配布元は GitHub Releases のほか、S3・HTTP・ローカルフォルダーなどを選べます。
- メリット:MSIX 不要。差分更新で軽量。GitHub Releases と相性が良い
- デメリット:更新の仕組みを自前で組み込む必要がある。MSIX ほどの OS レベルの管理はされない
どれを選ぶか(判断フロー)
- ストアに載せてよい → 方法A(Microsoft Store)。実装が最小で確実
- ストアは使わず、MSIX で自社配布したい → 方法B(App Installer)
- 従来どおり exe / ZIP で配りたい → 方法C(Velopack)
迷ったら、「ストアに出せるか → 出せないなら MSIX にできるか → それも無理なら Velopack」の順で降りていくと決めやすいです。
実装時の注意点
どの方法でも、共通して気をつけたい点があります。
- 署名は必須級:未署名だと SmartScreen 警告やインストール拒否につながる
- 更新チェックのタイミング:起動直後に同期的にやるとUXが悪い。バックグラウンドで確認し、次回起動時に適用が無難
- 失敗時の挙動:更新に失敗してもアプリが起動不能にならないこと。ロールバックや「今回はスキップ」を用意
- 設定ファイルの後方互換:更新でバージョンが上がると、古い設定が読めず壊れる事故が起きがち。堅牢なパースは 開発チェックリスト でも触れています
まとめ
WinUI デスクトップアプリの自動更新は、配布方法とセットで選ぶのが基本です。
- Microsoft Store:載せられるなら最も楽で確実
- MSIX + App Installer:ストア外で自動更新したいときの定番(署名必須)
- Velopack:exe / ZIP 配布に更新を足したいとき
最初のリリース前に「どう配って、どう更新を届けるか」まで決めておくと、後から作り直す手間を避けられます。配布の全体像は MSIX配布の記事、開発全体の抜け漏れ防止は チェックリスト記事 もあわせてどうぞ。
