はじめに
LINEのリッチメニューを管理するデスクトップアプリ「LichMenuLab」を開発する中で、知的財産(ライセンス判定ロジック等)の保護と、配布サイズの軽量化を目指して Native AOT に挑戦しました。
しかし、そこにはWinUI 3特有の深い闇が待っていました。本記事では、AOT断念の理由と、代替案としての難読化(Obfuscar)で直面した技術的トラブル、その解決策について共有します。
1. Native AOT への挑戦と、絶望の理由
当初、起動速度の向上とバイナリ解析防止のために .NET 9 の Native AOT を採用しようとしました。しかし、以下の理由により断念せざるを得ませんでした。
① ComboBox とデータバインディングの相性の悪さ
WinUI 3のバインディング({x:Bind})はコンパイル時にチェックされますが、データテンプレート内の型解決が Native AOT のトリミングによって実行時に失敗するケースが多発しました。特に ComboBox の SelectedItem 周りで型が欠落し、アプリが理由もなくアサートする現象に悩まされました。
② リフレクションの壁
多くのライブラリ(CommunityToolkit.Mvvm 等)が内部でリフレクションを使用しており、DynamicDependency をコード中に書きまくる作業が発生しました。「どこが消されたのか」を探すデバッグは、まさに「砂漠で針を探す」ような苦行でした。
③ 圧倒的な情報の少なさ
Microsoftの公式ドキュメントですら、WinUI 3 + Native AOT は「実験的」なニュアンスが強く、スタック・オーバーフローにも解決策が落ちていない。エンジニアとしての直感が「これはまだ本番で使うべきではない」と告げました。
2. 次の策:難読化(Obfuscar)への舵切り
Native AOT を諦め、従来の JIT コンパイルを維持しつつ、ロジックを隠蔽するために Obfuscar(オープンソースの難読化ツール)を導入しました。しかし、ここで新たな強敵が現れます。
直面したエラー:0xC000027B (アプリケーション内部例外)
難読化してビルドした瞬間、アプリが起動すらしない。ログも出ない。
ILSpyでバイナリを覗くと、原因は 「名前空間とクラスのリネーム」 にありました。
3. 難読化 vs JSONソースジェネレーターの競合
.NET 8 以降、難読化と相性の悪いのが JSON Source Generation (System.Text.Json) です。
失敗のメカニズム
- 難読化ツールがクラス名を
A.aに変える - ソースジェネレーターが生成したシリアライズ用コードは、元の名前
MyDataModelを探そうとする - リフレクションとトリミングの競合により、デシリアライズ時に「コンストラクタの引数名がnullである」といったエラーを吐いて沈む
解決策:ロジックの完全分離(CoreLogicパターン)
UIに関わるプロパティ(ViewModel等)は難読化をスキップし、「純粋なアルゴリズム」と「秘匿文字列」だけを internal な別クラスに切り出し、そこだけを狙い撃ちで難読化する手法を採りました。
<!-- UIやバインディングに関わる名前空間は死守する -->
<SkipNamespace name="LichMenuLab.ViewModels" />
<SkipNamespace name="LichMenuLab.Models" />
<!-- 核心ロジックが含まれるサービス層だけを難読化の対象とする -->
<Type name="LichMenuLab.Services.InternalCoreLogic" PreserveMethods="false" />
4. 教訓:WinUI 3開発における「現実的な」IP保護
今回の開発で得た知見は以下の通りです。
- Native AOT は時期尚早: WinUI 3 などのUIフレームワークと Native AOT の完全な調和には、まだ数年かかる?(苦行の好きな勇者が沢山現れるのを待つ)
- バインディング命: WinUI 3 はリフレクションへの依存度が低そうに見えて、内部的には名前(文字列)での紐付けが多いため、全体のリネーム難読化は自殺行為
-
Source Generator の活用: 難読化するクラスについても、JSON通信を行うなら手動で
JsonSerializerContextを定義し、名前の不一致をコンパイル時に埋める必要がある
結びに
「最新技術を全部盛り」しようとして地獄を見ましたが、最終的には「UIは標準、ロジックは難読化」という、メンテナンス性とセキュリティを両立した形に落ち着きました。
この苦闘の結果完成したアプリ「LichMenuLab」は、現在 Microsoft Store で公開中です。中身のロジックがどれだけぐちゃぐちゃに(難読化)されているか、興味がある方はぜひ覗いてみてください(笑)。
LichMenuLab:タブ付きリッチメニュー簡単作成
https://apps.microsoft.com/detail/9NBD0H4LQNX1