- Windowsネイティブアプリ開発エコシステムは、数十年にわたるフレームワークの断絶と繰り返される再設計により、2025年現在でも実質的な開発生産性を提供できていない状態にある
- Win32からMFC、WinForms、WPF、WinRT、UWPを経てWinUI 3に至る7段階のUIフレームワークの変遷にもかかわらず、最新APIだけでは基本的な機能すら実装できないケースが多数存在する
- トレイアイコン、グローバルショートカットのインターセプトなど日常的な機能が、いまだにP/InvokeによるWin32呼び出しに依存しており、最新フレームワーク導入の意義を薄れさせている
- .NET AOTコンパイル方式で単純なユーティリティアプリをビルドしても9MiBを超えるバイナリが生成され、MSIX配布のためのコード署名証明書には年間$200–300に達する現実的な障壁がある
- Microsoft自身の主要アプリ(VS Code、Outlook、スタートメニュー)がWeb技術で実装されているという事実は、Windowsネイティブ開発がMicrosoft内部でももはや優先事項ではないことを示している
背景: 何を作ったのか
- **Windows専用ユーティリティアプリ「Display Blackout」**の開発過程で、現在のネイティブアプリ開発環境の問題点が明らかになった
- このアプリはマルチモニター環境でゲーム中に左右の画面を黒いオーバーレイで消灯する機能を提供する
- 必要な機能は、ディスプレイ列挙、境界計算、グローバルショートカット処理、トレイアイコン表示、起動時の自動実行、設定保存など
- 既存のAutoHotkeyスクリプトやMicrosoft Storeアプリも存在したが、学習目的とUI改善のため自作を試みた
- 結果として、Windowsネイティブアプリ開発環境が極めて複雑で非効率的であることを確認した
Windowsプログラミングの歴史
- 初期にはCベースのWin32 APIが唯一の選択肢であり、このAPIは今日でもなお有効である
- C++ベースのMFCが、クラスやテンプレートなどのオブジェクト指向的抽象化をWin32の上に追加した
- **.NET 1.0(2002)**の導入により、C#言語とJITバイトコードVM、自動メモリ管理などが登場し、Windows FormsはWin32のウィンドウ・コントロールAPIのラッパーだった
- .NET 3.0(2006)のWPFはXAMLマークアップ言語を導入し、GPUベースのコントロール描画によってWin32依存から脱却しようとした最初の試みだった
- Windows 8(2012)のWinRTはサンドボックスアプリモデルを導入し、デスクトップ・タブレット・スマートフォンの統合を目指したが、XAML構造がWPFと微妙に異なり混乱を招いた
- Windows 10(2015)のUWPはサンドボックス制限を一部緩和したものの、WPFレベルのデスクトップ権限には及ばず、一部のOS機能(プッシュ通知、ライブタイル、Microsoft Store配布)はWinRT/UWP専用に制限された
- ChromeやMicrosoft Officeのような既存アプリが、WinRT/UWPブリッジアプリをIPCで接続する不格好なアーキテクチャを採用する一因となった
- Windows 11(2021)のWindows App SDKは、WinRT/UWP専用機能を標準C++および.NETアプリの両方に開放し、WinUI 3という新しいXAMLベースのコントロールライブラリを含んでいる
- UIフレームワーク進化の要約:
> Win32 C APIs → MFC → WinForms → WPF → WinRT XAML → UWP XAML → WinUI 3
開発方式選択のジレンマ
- WinUI 3アプリ開発には3つのルートがある:
- C++: スリムなバイナリ、Win32 C APIとの容易な相互運用 — ただしメモリ安全性がない
- C#/XAML + フレームワーク依存配布: 最新のWindows 11にも.NET 4.8.1しかプリインストールされておらず、初回インストール時に.NETライブラリのダウンロードダイアログが表示されるという劣悪なユーザー体験が発生する
- C#/XAML + .NET AOT: .NETランタイム全体(VM、GC、標準ライブラリ)をバイナリに含めるため、単純なアプリでも9MiB以上のバイナリが生成される
- Rustバインディング維持の試み(windows-app-rs)はアーカイブ済みとなった
- 配布方式の選択もまた苦痛である:
- MSIX形式はコード署名証明書が必要で、米国外居住者基準では年間**$200–300**かかる
- 署名なしのサイドロードには、管理者ターミナルでしか使えない難解なPowerShellコマンドが必要
- Microsoft Store登録は「独創的で継続的な価値」を提供していないことを理由に却下された
最新SDKでも不可能な機能
| 機能 |
Windows App SDKの対応状況 |
| ディスプレイ列挙 |
部分的に可能(foreachループ不可、変更検知にはP/Invokeが必要) |
| 非アクティブな黒ウィンドウの配置 |
部分的に可能(non-activatingにはP/Invokeが必要) |
| グローバルキーボードショートカットのインターセプト |
不可 — P/Invokeが必要 |
| 起動時の自動実行 |
可能(システム設定連携APIを提供) |
| 設定の永続保存 |
可能 |
| トレイアイコン + メニュー |
不可 — P/Invokeが必要、メニュースタイルも標準化されていない |
- トレイアイコンメニューのスタイルはアプリごとにばらばらで、OS全体を通じて一貫した標準が存在しない
- WPFからWinUI 3へ移る過程で、ウィンドウサイズの自動調整のような基本機能すら失われている
C#とWin32相互運用の構造的限界
- モダンなP/InvokeツールであるCsWin32には、構造体内部の文字列を正しくラップできないバグが存在する
- CsWin32のドキュメントには、Win32 APIの基本パラメータ型である
[optional, out]をC#で慣用的に表現する方法がないため、同じメソッドを2種類のバージョンで生成すると明記されている
- WPFリリース(2006)から20年が経った現在でも、UIバインディング用クラス作成のボイラープレートはほとんど改善されていない
- すべてのプロパティをgetter/setterの組に変換し、同値ガードやイベント発火呼び出しなどの繰り返しコードが依然として必要
- JavaScriptのデコレータやプロキシに相当する言語レベルの解決策が、20年間C#に追加されていない
- CsWin32は変更履歴の内容が乏しく、1.0未満のバージョンにとどまっているため、数年以内にプロジェクトが放棄される可能性があるように見える
結論: なぜElectronが答えなのか
- 現在、Microsoftはネイティブアプリ開発を優先していない
- 関連イシュートラッカーはバグとレポートで溢れているが、Microsoftエンジニアからの応答はほとんどない状態
- Windows App SDKの変更ログは機械学習API追加が中心
- VS Code、Outlook、スタートメニューなどMicrosoft自社の主要アプリがWeb技術で実装されている事実が、それを裏付けている
- コミュニティはAvalonia、Uno PlatformのようなサードパーティUIフレームワークへ移行しつつある
- これらはWPFの哲学を継承し、クロスプラットフォーム対応を強化している
- 現時点では、ElectronやTauriのようなWebベースのフレームワークのほうが現実的な選択肢である
- TypeScript/React/CSSの組み合わせはC#/XAMLより生産的であり
- Win32 APIへのアクセスも可能
-
TauriはシステムWebViewを活用するためChromiumバンドルが不要
- WebView2ランタイムは4週間ごとに更新される一方、システム.NETは4.8.1に固定されている
- MicrosoftがWindows App SDK改善と配布体系の簡素化を進めれば回復の可能性はあるが
- 現状ではほとんどの開発者は期待していない
- 結論として「Webスタックを選ぶ」という判断で締めくくられる
- Microsoftの最近のWindows品質重視の発表には、OS全体でWinUI 3をさらに多く使うという内容が含まれているが、実質的な改善につながるかは不透明
3件のコメント
Electronで正常化してくださるので……
WinUI 3 の WYSIWYG はいつ出るんだろうなあ
Hacker Newsの意見
自分も他の人たちと同じく、Win32を使い続けるのが正しいと思う
長年Win32で開発してきた立場からすると、必要な機能は8KB以下のスタンドアロン実行ファイルで十分実装できる
ディスプレイ列挙、ウィンドウ作成、ショートカットのフック、スタートアップ登録、設定保存、トレイアイコン表示など、すべて数百バイト程度のAPI呼び出しで可能だ
とはいえ、2026年に新規プロジェクトを**メモリ安全でない言語(C++)**で書くのは時代遅れだ
ただし、信頼できない入力がほとんどないアプリなら、わざわざプロパガンダに振り回される必要はない
_UNICODEの問題を避けたいなら、.NET Frameworkで半分の時間で同じものを作れる「NoFramework」運動が再び現れて、RADの時代に戻るべきだと思う
ただ、新規プロジェクトでC++を選ぶのは慎重であるべきだ
メモリ安全な言語からでもWin32は使える — たとえば windows-rs
当時はBorland Delphiが最も人気のあるツールだった
既存のWinRT、UAP、UWPアプリでないなら、WinUI 3.0やWinAppSDKは避けるべきだ
Win32、MFC、WinForms、WPFのような実績ある技術を使い続けるほうがよく、
Microsoftの外のエコシステムならQt、VCL、Firemonkey、Avalonia、Uno、ImGUIなどを検討できる
WinUI 3.0はあまりにひどく、Microsoftでさえコミュニティにオープンソースとして渡そうとしている
その後 WinJS がオープンソースのWebフレームワークへ転換し、公式サポートが打ち切られた
関連ブログ記事
組み込み開発者だが、デバイスと通信するWin32 GUIプログラムを作るのは今でも簡単だ
XP時代のコードがWindows 11でもそのまま動き、VC6プロジェクトをVisual Studio 2022で開いても問題なくビルドできる
こうした下位互換性は他のプラットフォームではなかなか見られない
AppleのCocoaは構造としては「エレガント」だが、実際には複雑でドキュメントも不親切だ
純粋なWin32 APIは今でも実用的な選択肢だ
C++でMFCに似たラッパーを自作すれば2〜3週間で完成でき、その後は完全な制御権を持てる
Microsoftの強力な下位互換性のおかげで、Win32ベースのアプリは長期的に安定している
10年以上アップデートしてきた例を ここ で見られる
システムカラーやコントロールがハードコードされていて、暗いテーマと衝突する
メニューやメッセージボックス、ファイルダイアログなど一部のUIしかダークモードをサポートしておらず、一貫性が崩れる
関連する議論は この記事 を参照
現在はオープンソースで保守されており、バージョン10まで出ている
Windowsアプリをいくつも作ってきた経験からすると、
(1) Win32 APIは古いが非常に安定しており、
(2) Microsoft製のUIツールキットは避けるべきだ — 結局Win32レベルの制御が必要になる
この20年間でMicrosoftが作ったUI技術の大半はWPFの派生形だった
WPFを継続して発展させていれば、今ごろUI開発の標準になっていただろう
ユーザーの立場ではネイティブアプリは高速で良いが、開発は本当に複雑な混沌だ
OutlookやTeamsのようなアプリがどんどん悪くなっている理由もこれだ
フォーカスやキーボードナビゲーションなどでネイティブらしさを再現するのは難しい
Electrobunプロジェクト 参照
「C++で新規プロジェクトを作るのは犯罪だ」という言葉には同意しない
GUIでは安全性より性能と制御が重要で、C++は今なお実績ある言語だ
Qtは2026年でも最高のGUIフレームワークの一つであり、メモリ安全機能を内蔵している
なぜ最新の**.NETランタイムがWindows 11に標準搭載されていないのか疑問だ
これはMicrosoftが一貫したユーザー体験**を放棄したもう一つの例に見える
Windows Updateですべて配布するのは非現実的だ
その代わり AOTコンパイルされたスタンドアロン実行ファイルとして配布できる(約9MiB)
Electronよりはるかに小さく効率的だ
今ではDLLを同梱してパッケージ化するほうがよい
OSに組み込むのが難しくなった
高速なリリースサイクルを維持するためにOSアップデートから切り離したのだ
.NET Coreは別途インストールが必要な構成になっている
久しぶりにTauriでWindowsとMac向けのアプリを作ってみたが、
開発とビルドは簡単だった一方で、コード署名の問題で同僚がインストールできなかった
Macではターミナルコマンドで解決できたが、Windowsでは Smart App Control を無効にする必要があり、
この機能は再インストールなしでは再度有効にできない
セキュリティ目的は理解できるが、インストール手順がここまで難しいとは思わなかった
「なぜElectronを使わないのか」という問いへの答えは簡単だ —
Electronアプリはユーザー体験が悪い
開発は簡単だが、性能と品質を犠牲にする
良い製品を作りたいなら、難しくてもネイティブに行くべきだ
個人的には C#のほうがTypeScriptよりはるかに優れている と思う