14 ポイント 投稿者 GN⁺ 2026-03-23 | 3件のコメント | WhatsAppで共有
  • 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技術で実装されている事実が、それを裏付けている
  • コミュニティはAvaloniaUno 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件のコメント

 
vndk2234 2026-03-24

Electronで正常化してくださるので……

 
carnoxen 2026-03-23

WinUI 3 の WYSIWYG はいつ出るんだろうなあ

 
GN⁺ 2026-03-23
Hacker Newsの意見
  • 自分も他の人たちと同じく、Win32を使い続けるのが正しいと思う
    長年Win32で開発してきた立場からすると、必要な機能は8KB以下のスタンドアロン実行ファイルで十分実装できる
    ディスプレイ列挙、ウィンドウ作成、ショートカットのフック、スタートアップ登録、設定保存、トレイアイコン表示など、すべて数百バイト程度のAPI呼び出しで可能だ
    とはいえ、2026年に新規プロジェクトを**メモリ安全でない言語(C++)**で書くのは時代遅れだ
    ただし、信頼できない入力がほとんどないアプリなら、わざわざプロパガンダに振り回される必要はない

    • メモリ安全性と_UNICODEの問題を避けたいなら、.NET Frameworkで半分の時間で同じものを作れる
    • 昔はDelphiやMFCのような薄いレイヤーがこうした問題を解決していたが、今では流行が過ぎ、代替もない
      NoFramework」運動が再び現れて、RADの時代に戻るべきだと思う
    • Win32には今も豊富なドキュメントとツールがあり、これからも長く生き残るはずだ
      ただ、新規プロジェクトでC++を選ぶのは慎重であるべきだ
      メモリ安全な言語からでもWin32は使える — たとえば windows-rs
    • 一般ユーザーの目にWin32アプリをきれいに見せるにはどうすればいいのか気になる
    • Winampの開発者たちは、どうやってあれほど優れたWin32アプリを作ったのだろう
      当時は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でWindows 8アプリを作ってWindows Storeに公開したことがある
      その後 WinJS がオープンソースのWebフレームワークへ転換し、公式サポートが打ち切られた
    • 最近のブログで「Windowsの中核体験をWinUI3へ移行する」という発表があったが、品質改善のための措置とはいえ不安だ
      関連ブログ記事
  • 組み込み開発者だが、デバイスと通信するWin32 GUIプログラムを作るのは今でも簡単だ
    XP時代のコードがWindows 11でもそのまま動き、VC6プロジェクトをVisual Studio 2022で開いても問題なくビルドできる
    こうした下位互換性は他のプラットフォームではなかなか見られない

    • むしろ無骨なWin32コードを使い続けるほうがいいと感じる
      AppleのCocoaは構造としては「エレガント」だが、実際には複雑でドキュメントも不親切だ
    • 最近の開発者は毎週変わるエコシステムに慣れていて、古いものを「保守されていないもの」だと見なしがちだ
    • ただし、高解像度DPIや入力処理の問題などは今でも厄介だ
    • 32ビットから64ビットへの完全移行が最大の課題だった
    • 文字列定義の方法が多すぎて混乱する
  • 純粋なWin32 APIは今でも実用的な選択肢だ
    C++でMFCに似たラッパーを自作すれば2〜3週間で完成でき、その後は完全な制御権を持てる
    Microsoftの強力な下位互換性のおかげで、Win32ベースのアプリは長期的に安定している
    10年以上アップデートしてきた例を ここ で見られる

    • ダークモード対応が最大の問題だ
      システムカラーやコントロールがハードコードされていて、暗いテーマと衝突する
      メニューやメッセージボックス、ファイルダイアログなど一部のUIしかダークモードをサポートしておらず、一貫性が崩れる
    • このアプローチではWindows 11風のUIは作れない
      関連する議論は この記事 を参照
    • WTL 3.0 を使っていたが、MFCよりずっと軽量で、Win32機能にすべてアクセスできた
      現在はオープンソースで保守されており、バージョン10まで出ている
    • MFCスタイルのラッパーのAPI設計をうまくやれば、AIが実装を代わりに書いてくれるかもしれない
    • いっそ C++ BuilderやDelphi を使ったほうがいいのでは、という意見もある
  • Windowsアプリをいくつも作ってきた経験からすると、
    (1) Win32 APIは古いが非常に安定しており、
    (2) Microsoft製のUIツールキットは避けるべきだ — 結局Win32レベルの制御が必要になる

    • ただし WPFとWinForms は例外的に安定している
      この20年間でMicrosoftが作ったUI技術の大半はWPFの派生形だった
      WPFを継続して発展させていれば、今ごろUI開発の標準になっていただろう
  • ユーザーの立場ではネイティブアプリは高速で良いが、開発は本当に複雑な混沌
    OutlookやTeamsのようなアプリがどんどん悪くなっている理由もこれだ

    • 皮肉なことに、OutlookとTeamsがそうした問題を抱えているのは**Webアプリベース(Electron)**だからだ
      フォーカスやキーボードナビゲーションなどでネイティブらしさを再現するのは難しい
    • 自分も個人用ツールを作るときは TypeScript + Bun + Electrobun の組み合わせを使っている
      Electrobunプロジェクト 参照
    • Microsoft自身がElectronでアプリを作っているのだから、他の開発者に何を期待できるだろうか
  • 「C++で新規プロジェクトを作るのは犯罪だ」という言葉には同意しない
    GUIでは安全性より性能と制御が重要で、C++は今なお実績ある言語だ
    Qtは2026年でも最高のGUIフレームワークの一つであり、メモリ安全機能を内蔵している

    • ただしQtが真にネイティブに動作するのは一部のLinuxディストリビューションだけだ
    • Qtアプリはランタイムを必要とするため、完全なネイティブとは言い難い
    • もちろんマネージド環境に比べれば不便だが、組み込み環境では今でも有用だ
  • なぜ最新の**.NETランタイムがWindows 11に標準搭載されていないのか疑問だ
    これはMicrosoftが
    一貫したユーザー体験**を放棄したもう一つの例に見える

    • .NETのバージョンが多すぎて完全な下位互換もないため、
      Windows Updateですべて配布するのは非現実的だ
      その代わり AOTコンパイルされたスタンドアロン実行ファイルとして配布できる(約9MiB)
      Electronよりはるかに小さく効率的だ
    • 昔はWindows Updateで配布していたが、アップデートがアプリを壊したり、サイズが大きすぎて非効率だった
      今ではDLLを同梱してパッケージ化するほうがよい
    • .NET 5以降、セキュリティモデルと名前空間が大きく変わり、
      OSに組み込むのが難しくなった
      高速なリリースサイクルを維持するためにOSアップデートから切り離したのだ
    • 現在はレガシーな.NET FrameworkがOSに含まれ、
      .NET Coreは別途インストールが必要な構成になっている
  • 久しぶりにTauriでWindowsとMac向けのアプリを作ってみたが、
    開発とビルドは簡単だった一方で、コード署名の問題で同僚がインストールできなかった
    Macではターミナルコマンドで解決できたが、Windowsでは Smart App Control を無効にする必要があり、
    この機能は再インストールなしでは再度有効にできない
    セキュリティ目的は理解できるが、インストール手順がここまで難しいとは思わなかった

  • 「なぜElectronを使わないのか」という問いへの答えは簡単だ —
    Electronアプリはユーザー体験が悪い
    開発は簡単だが、性能と品質を犠牲にする
    良い製品を作りたいなら、難しくてもネイティブに行くべきだ
    個人的には C#のほうがTypeScriptよりはるかに優れている と思う