Windowsアプリのシングルバイナリ化の知識マップ(知識グラフ)
Windowsアプリは配布物を1個のEXEへ寄せること自体はかなり可能で、.NETのself-containedやsingle-file・Native AOT、C/C++の静的リンク(/MT)が使えるが、OSバージョンやアーキテクチャ、システムDLL、セキュリティモデルへの依存は残り、対象Windowsへの依存をゼロにはできない。self-containedとframework-dependentは排他的な選択肢で、Native AOTは実質single-fileとして動く代わりに組み込みCOMなどが使えなくなる。WebView2はEvergreenかFixed Versionかでランタイムの提供方法を選ぶ必要があり、WinUI 3はpackaged(MSIX)かunpackagedかでPublishSingleFileの可否が変わる。Shell拡張やドライバーは登録・署名の設計が本題になるため、無理に1EXEへ圧縮するよりapp-local配布のほうが保守しやすいことが多い。
シングルバイナリ化(1ファイル配布)
アプリの配布物を実行ファイル1個にまとめて配ることを指す、Windowsアプリの配布方式。
1EXE配布
対象Windowsへの依存
OSバージョン・CPUアーキテクチャ・システムDLL・セキュリティモデルなど、アプリが実行時に前提とする対象Windows側の要素への依存。
OS依存
Windows依存
self-contained発行
アプリの実行に必要な.NETランタイム一式も一緒に配布する発行形式。
framework-dependent発行(.NET)
対象機に事前インストールされた.NETランタイムに依存する.NETの発行形態。
Native AOT
.NETアプリを単一のネイティブバイナリへ事前コンパイルする発行方式。非対応リストにC++/CLIが明記されている。
built-in COM interop
WindowsがOS標準で提供するCOM相互運用機構。Native AOTには存在しない。
single-file発行(.NET)
発行時に配布物を1個の実行ファイルへまとめる.NETの発行オプション。
CRTの静的リンク(/MT)
MSVCでUCRT・VC++ランタイムをDLLとしてではなく実行ファイルへ静的にリンクするコンパイラオプション。
CRTの動的リンク(/MD)
MSVCでUCRT・VC++ランタイムを対象機のDLLとして参照するコンパイラオプション。
Visual C++ 再頒布可能パッケージ
Visual C++で作られたアプリケーションやコンポーネントの実行に必要なランタイムDLLをまとめて配布するパッケージ。
Visual C++再頒布可能パッケージ
UCRT(Universal C Runtime)
Visual Studio 2015でCランタイムが分割されてできた標準Cライブラリ部分で、Windows 10以降はOSの構成要素として同梱される。
MSIXパッケージング(packaged)
package identityを持たせてアプリを配布するWindowsのパッケージング形式。
WinUI 3 / Windows App SDK
パッケージング方式(packaged/unpackaged)とランタイム方式(framework-dependent/self-contained)の組み合わせで配布要件が決まる、Windowsデスクトップアプリ向けのUIフレームワーク。
Microsoft Edge WebView2
Chromiumベースのランタイムを使ってWindowsアプリにWeb描画エンジンを埋め込む仕組み。WebBrowserコントロールの完全な差し替え部品ではない。
WebView2 Runtime
WebView2アプリの実行に必要な、Chromiumベースの描画エンジンを提供するランタイム。
Evergreen配布モード(WebView2)
Microsoftが自動更新する共有のWebView2 Runtime1本を全アプリで利用させる配布モード。
Fixed Versionランタイム
特定バージョンのWebView2ランタイムをアプリに同梱する配布方式。動作検証済みの構成を凍結できる一方、同梱物が250MBを超え、ブラウザーエンジンの脆弱性修正を自分のリリースで配る責任を負う。
シェル拡張(エクスプローラー拡張)
右クリックメニューやアイコン表示など、エクスプローラーへ組み込まれる部品。
COM(コンポーネントオブジェクトモデル)
公開インターフェース、レジストリ登録、Apartment Modelなどを土台にした、Windowsのバイナリ互換コンポーネントモデル。
ドライバー署名
INFファイルによるインストール定義と署名を含めて成立する、Windowsドライバーの配布・インストールに必要な一連の要件。
ドライバーパッケージ
デバイスドライバーをシステムへ導入するためのパッケージで、通常のアプリ配布方式とは別問題として扱われる。
デバイスドライバーの導入パッケージ
app-local配布(アプリ隣接配布)
DLLをEXEと同じフォルダーに置き、そのアプリからだけ読み込ませる配布形態。
xcopy配布
配布物を1個のEXEへ寄せても、OSバージョン・アーキテクチャ・システムDLL・セキュリティモデルへの依存は消えず、アプリの実行は対象Windowsを前提とし続ける
self-containedと framework-dependentは同じ発行に対して排他的な選択肢で、RuntimeIdentifierを指定するとSelfContainedは既定でtrueになる
Native AOTでは動的読み込みやC++/CLIに加え、Windows上の組み込みCOMが使えなくなる
Windows向けにsingle-fileで発行する場合、出力はOS・アーキテクチャ固有になるため、最低サポートWindowsとarchを先に固定する必要がある。single-file発行自体はLinux・macOSも対象にできるので、対象Windowsへの依存が生じるのはWindowsをターゲットに選んだときに限られる。
Native AOTも対象プラットフォームが決め打ちで、AnyCPUで1個という発想は成立しない。Native AOT自体はLinux・macOSも対象にできるので、対象Windowsへの依存が生じるのはWindowsをターゲットに選んだときに限られる。
/MTと/MDは同じコンパイル対象に対して選ぶMSVCの排他的なリンクオプションである
/MDでリンクした実行ファイルは、対象機にUCRTとVC++ランタイムのDLLが入っていることを前提とする
/MTはlibucrt.libなどUCRT・VC++ランタイムを実行ファイルへ静的にリンクする
/MDはucrt.libというDLL用インポートライブラリを使い、実行時にucrtbase.dllを参照する
packagedなWinUI 3アプリ、および外部の場所を指すpackagedなアプリではPublishSingleFileは使えない
WinUI 3はpackaging軸としてMSIXなどのpackaged形式を選べる
WebView2ベースのUIを動かすには、Chromiumベースの描画エンジンを提供するWebView2 Runtimeが対象機に必要になる
WebView2 Runtimeの提供方法として、Microsoftが自動更新する共有の1本を使うEvergreenを選べる
WebView2 Runtimeの提供方法として、特定バージョンをアプリごとに同梱するFixed Versionを選べる
EvergreenとFixed Versionは同じアプリに対して選ぶ排他的な配布モードである
Shell拡張はExplorerなどのプロセスへ読み込まれて動作するCOMコンポーネントとして実装される
ドライバーの署名はSYS単体ではなく、INF・CAT・SYSを含むドライバーパッケージ一式に対して行われ、OSもパッケージ単位でドライバーストアへ配置する
インストールされたドライバー本体は、上のパッケージ一式をドライバーストアへ配置する形でしか成立せず、1個のEXEを置くだけでは動かないため、single binary化の対象には向かない。ただし配布物としては、署名済みパッケージを同梱して展開・インストールするブートストラッパーEXE1個にまとめること自体は可能である
app.exeと隣接DLL数個をインストーラー不要・管理者権限不要でxcopy配布できるなら、無理に1EXEへ圧縮するより保守しやすいことが珍しくない
self-contained発行はRuntimeIdentifier(対象OS/アーキテクチャ)ごとに.NETランタイムを同梱する形態なので、single-fileやNative AOTと同様に最低サポートWindowsとarchを先に固定する必要がある。self-contained発行自体はLinux・macOSも対象にできるので、対象Windowsへの依存が生じるのはWindowsをターゲットに選んだときに限られる。
レベルB(言語ランタイムの事前インストール不要)を実現する手段として、ネイティブC/C++では/MTによるCRTの静的リンクを利用できる
WebView2を採用すると単独起動EXEにはないWebView2 Runtimeという追加ランタイムへの依存が生じ、対象Windows側の依存(ホストやランタイム依存)が増える