「エミュレーターではブレークできるのに、物理デバイスに配布した署名付き APK では即座にデバッガが切断される」――.NET MAUI の In‑App Billing 検証でつまずく典型例です。本記事では、Visual Studio 2022(.NET 8/Android API 34)環境で発生する The vsdbg debug session … has been stopped の原因と、現実的で安全な回避策、そして実機で課金フローをテストするための準備・チェックリスト・深掘りトラブルシュートを、コピペで運用に載せられるレベルまで具体的に整理します。
起きていること:症状の全体像
以下に当てはまる場合、本記事の内容が有効です。
- Visual Studio 2022 上で .NET MAUI Android プロジェクト(.NET 8/API 34)を「デバッグ」実行。
- USB デバッグが有効な物理 Android 端末に対して、署名付き APK を展開。
- アプリは端末上で起動するが、IDE 側では即座に
The vsdbg debug session … has been stopped表示となり、ブレークポイントに到達できない。 - 同一ソリューションをエミュレーターに向けて実行した場合は、ブレークポイント・ウォッチ・ステップ実行など通常どおり可能。
| 環境/条件 | ふるまい | 補足 |
|---|---|---|
| 実機(USB 接続)+署名付き APK | アプリは起動するが、IDE のデバッガは即切断 | vsdbg セッションが強制終了 |
| Android エミュレーター | 問題なし。ブレーク可能 | 同じブレークポイントで停止 |
| In‑App Billing の検証 | 実機での検証が必須 | 課金ダイアログはエミュレーターでは不安定・条件付き |
結論:原因は「.NET Mono Debugger for MAUI apps」プレビュー機能の不具合
Visual Studio 2022 17.14 以降で導入されたプレビュー機能 .NET Mono Debugger for MAUI apps が、物理デバイスに対するデバッガ アタッチ時に正しく動作せず、セッションを異常終了させる既知の不具合が原因です。エミュレーターでは影響が出ないため、現象が「実機限定」であることと整合します。
執筆時点(2025 年 11 月 1 日)で恒久対策(安定版での修正配布)は公開されていません。したがって、当面はプレビュー機能を無効化することが最も副作用の少ない回避策になります。
| 要素 | 内容 |
|---|---|
| 影響バージョン | Visual Studio 2022 17.14 以降(プレビュー機能が既定で有効化されている/され得る構成) |
| 影響対象 | 物理 Android 実機に対するデバッグ(署名付き/未署名を問わず発生し得るが、署名付き APK の検証で顕在化しやすい) |
| 非影響 | Android エミュレーターでのデバッグは概ね正常 |
| 発生メッセージ | The vsdbg debug session … has been stopped |
| 既知の対処 | 該当プレビュー機能を無効化して VS を再起動 |
最短で復旧する回避策(推奨手順)
- Visual Studio のメニューから 「ツール > オプション > 環境 > プレビュー機能」 を開きます。
- 一覧から 「.NET Mono Debugger for MAUI apps」 のチェックを外します。
- Visual Studio を再起動します。
- USB で接続した物理端末をターゲットにして、プロジェクトを 「デバッグ」実行します。
これで、ブレークポイント停止・変数ウォッチ・ステップ実行など、これまでどおりのデバッグ体験が復活します。In‑App Billing のように「実機限定の UI/アカウント連携」が絡む機能の検証も可能になります。
「本当にそれが原因?」を切り分ける確認ポイント
プレビュー機能の無効化で直る見込みが高いとはいえ、開発現場では他要因の混入も起こりがちです。次の観点で併せて確認しましょう。
| チェック項目 | 期待状態 | 確認方法 |
|---|---|---|
| USB デバッグ許可 | 端末側で該当 PC を「常に許可」 | 初回接続時の RSA 指紋ダイアログで許可/adb devices が device 表示 |
| Google USB ドライバー | 正しく導入・競合なし | デバイス マネージャーで警告なし/複数ドライバーの同時適用なし |
| 署名・ビルド構成 | Debug 構成(推奨)。Release でも可だが注意点あり | VS の構成マネージャーを確認。Release で android:debuggable を無闇に有効化しない |
| ADB ポート競合 | 不要なブリッジ/古い ADB が残っていない | adb kill-server → adb start-server で再起動 |
| エミュレーター常駐 | 実機優先でアタッチされる | 不要なエミュレーターを停止(ターゲット誤選択を防ぐ) |
| vsdbg 関連の拡張/プレビュー | 該当プレビューを無効化 | 「プレビュー機能」でチェックを外し VS を再起動 |
In‑App Billing/Google Play 課金の実機テストを安定させる実務ノウハウ
課金機能は「Google アカウント」「Play ストア」「署名」「配布チャネル」の 4 点が絡むため、デバッガ問題を解いたあとも手順の最適化が鍵になります。以下は現場でトラブルを減らす実務的な流れです。
推奨フロー(内製チーム向け)
- 対象端末に テスト用 Google アカウントをサインイン(本番課金アカウントを使わない)。
- Play コンソールで ライセンステストにテストアカウントを登録。
- 内部テストトラック/内部アプリ共有を使い、Play 経由で配信するビルドも用意(課金フローの最終動作確認用)。
- 日常のデバッグでは、VS から USB 直デプロイ(本記事の回避策適用済み)を使って素早く反復。
- 商品 ID/価格テンプレート/消費型・非消費型/サブスクリプションの SKU 設計を固定し、アプリ内の文字列を 定数・設定化(打鍵ミスを防止)。
課金テストの落とし穴と対処
| 現象 | 主因 | 対処 |
|---|---|---|
| 購入ダイアログが出ない | Play ストアのアカウント未連携/SKU 未公開/ビルド署名不一致 | テストアカウントの登録/内部テスト公開/同一署名で配布 |
Result が ItemUnavailable | SKU が Draft/国/価格設定が未完了 | 対象国の価格を確定/公開ステータスへ |
| 消費型が二重購入できない | 未消費のトランザクションが残存 | 購入後に 必ず消費 API を呼ぶ/開発者コンソールで状態確認 |
| サブスクの状態が反映されない | レシート検証の遅延/キャッシュ | バックエンド側でレシート検証を実装し、アプリはサーバー結果を信頼 |
Release/Debug と「署名付き APK」「デバッグ可能」の正しい関係
「署名付き APK = Release = デバッグ不可」と誤解されがちですが、.NET MAUI/Android では次の整理が重要です。
- Debug 構成:通常は
android:debuggable="true"。VS から USB デプロイすればブレーク可能。 - Release 構成:通常は
android:debuggable="false"。ただし、特定用途でデバッグ可能ビルドを作ることは原理的には可能(ただし本番配布は不可)。 - 「署名」は配布要件(Play でもローカル配布でも必要)が主目的で、デバッグ可否は構成とマニフェストが決めます。
.csproj の代表的なトグル(知っておくと便利)
<PropertyGroup Condition="'$(Configuration)'=='Debug' and '$(TargetFramework)'=='net8.0-android'">
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime>
<AndroidLinkMode>None</AndroidLinkMode>
<DebugType>portable</DebugType>
</PropertyGroup>
False
SdkOnly
True
上記は一例です。Release 構成で DebugSymbols を活かして「障害解析しやすい最適化ビルド」を作り、デバッガは Debug 構成で確実に当てる、といった運用が現実的です。
ADB/デバッガ視点での深掘りトラブルシュート
回避策を適用しても稀に別要因でセッションが切れることがあります。対話的に切り分けましょう。
ADB をリセット
adb kill-server
adb start-server
adb devices
devices の出力が device(認証済み)であることを確認。unauthorized の場合は端末側で RSA 許可ダイアログに応答します。
ポートフォワードの確認
adb forward --list
不要なフォワーディングが大量に残っている場合はリセットを検討。別ツールが :5037 を掴んでいると不安定になります。
logcat を並行観測
adb logcat | findstr /i "mono debug vsdbg crash exception"
例外やプロセス終了の痕跡がないかを確認。アプリ側例外でプロセスが終了していると、デバッガ切断と見分けがつかないことがあります。
デプロイ キャッシュの掃除
- 端末から対象アプリをアンインストール。
- VS メニューから 「クリーン」→「再ビルド」。
- 再デプロイ。
拡張・プレビューの総点検
問題のプレビュー機能以外にも、サードパーティ拡張がデバッガに介入していることがあります。再現しやすいチーム PC を 1 台決め、拡張最小構成での再現性を確かめると切り分けが進みます。
エミュレーターでは起きない理由(実機限定になる背景)
本件が「エミュレーターでは再現しない」最大の理由は、デバッガのアタッチ経路と実機の OS/ベンダー依存差です。実機では USB ブリッジ越しに 実デバイス の zygote/アプリプロセスへ接続しますが、エミュレーターはホスト OS 上の仮想化レイヤーで統一化され、デバッガのハンドシェイク差分が少なくなります。今回のプレビュー機能は、この「アタッチ時ハンドシェイク」を置き換える要素を含むため、実機で不具合が顕在化しやすい構造です。
チームですぐ使えるチェックリスト(配布可能テンプレート)
- [ ] VS 2022 の プレビュー機能で .NET Mono Debugger for MAUI apps のチェックを外した。
- [ ] 端末は 開発者向けオプションと USB デバッグが有効。
- [ ] Google USB ドライバーが正しくインストールされ、デバイス マネージャーに警告なし。
- [ ] Debug 構成でデプロイ(または Release 構成でもデバッグ可否の設計を理解して運用)。
- [ ] adb kill-server/start-server 後に
deviceと認識されている。 - [ ] In‑App Billing の テストアカウント/SKU/内部テストが設定済み。
- [ ] エミュレーターは不要なら停止し、ターゲット誤選択を防止。
- [ ] アプリの初回起動後、Play ストアの更新/キャッシュを必要に応じてクリア(課金ダイアログ遅延を避ける)。
現象別・一発把握テーブル
| 現象 | 第一候補の原因 | 一手目の対処 | 次の一手 |
|---|---|---|---|
| 実機だけ即切断 | .NET Mono Debugger for MAUI apps が有効 | プレビュー機能を無効化→VS 再起動 | ADB リセット、拡張最小化 |
| 署名付き APK でブレークしない | Release 構成で debuggable=false | Debug 構成で検証 | Release は記号情報付与で解析運用へ切替 |
| 課金ダイアログが出ない | SKU 未公開/テストアカウント未登録 | 内部テスト公開&アカウント登録 | Play ストアのキャッシュ/アカウント再同期 |
| エミュレーターは常に OK | 実機特有のデバッガ経路差 | 今回の回避策を適用 | logcat で例外を監視しアプリ側の落ちも除外 |
安全性・コンプライアンスの観点
- Release 構成に無理に
android:debuggable="true"を付与して配布するのは避けましょう。セキュリティリスクと審査リスクが高まります。 - テスト用と本番用の署名鍵を厳密に分離し、鍵管理をルール化(キーストアの保管・権限分離・ローテーション)。
- 課金動作の最終確認は Play 経由のビルドで行い、サーバー側検証を組み込んだ上で QA フリーズへ。
社内ナレッジに落とし込む(再発防止)
- 環境差分表を Confluence 等に常設(VS バージョン、プレビュー機能フラグ、Android SDK/NDK/ビルドツールのバージョン)。
- 新規メンバーの PC セットアップ手順に、プレビュー機能の既定設定を明記。
- CI のビルドログと PDB/シンボルの保管を自動化(障害解析の再現性を担保)。
- 課金 SKU の命名規約・価格改定フロー・テストアカウント棚卸しを四半期ごとに実施。
FAQ
Q. 17.13 以前へダウングレードした方が早い?
A. 組織運用ではダウングレードは副作用が大きいことが多く、まずは プレビュー機能の無効化で対処するのが安全です。どうしても他の不具合に該当する場合のみ、影響範囲を評価した上で検討しましょう。
Q. エミュレーターだけで課金を検証しても良い?
A. 開発中の動作確認には有用ですが、アカウント課金・決済 UI・Play サービス更新のタイミングなど、実機でしか再現しない条件が複数あります。最終的な QA は実機で行うのが原則です。
Q. 「署名付き APK」だとデバッグ不可なのでは?
A. 署名の有無とデバッグ可否は別問題です。Debug 構成で署名した APKを USB デプロイすればブレークできます。本番配布の Release ではデバッグ不可で OK、解析はシンボルで行うのが一般的です。
Q. 回避策適用後も稀に切断する
A. ADB の競合・拡張機能・セキュリティソフトのフックなど別要因が潜むことがあります。logcat 監視と 拡張最小化、そして 別 PC/別ケーブル/別端末での再現確認が効果的です。
まとめ:いま実務で取るべき一手
物理デバイスで .NET MAUI Android アプリをデバッグできない場合は、まず Visual Studio のプレビュー機能 .NET Mono Debugger for MAUI apps を無効化して再起動――これが最短で確実な復旧策です。復旧後は、In‑App Billing のテスト基盤(テストアカウント/SKU/内部配信)を整え、Debug 構成での USB 反復と Play 経由の最終確認を二段構えにすることで、課金機能の品質と速度を両立できます。チームには「環境差分表」「プレビュー機能の既定」を残し、再発を未然に防ぎましょう。
付録:現場でそのまま使えるスクリプトとメモ
ADB メンテコマンド(コピペ用)
:: ADB を再起動
adb kill-server
adb start-server
:: 端末認識の確認
adb devices
:: 端末ログの監視(Windows)
adb logcat | findstr /i "mono vsdbg exception crash"
:: 端末ログの監視(macOS/Linux)
adb logcat | grep -i "mono|vsdbg|exception|crash"
Release ビルドでも解析しやすくする最低限の設定例
<PropertyGroup Condition="'$(Configuration)'=='Release' and '$(TargetFramework)'=='net8.0-android'">
<DebugSymbols>True</DebugSymbols>
<DebugType>portable</DebugType>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
</PropertyGroup>
Play ストア関連メモ
- SKU の ID は 英小文字・数字・ピリオドに限定し、アプリ ID と同様の命名規約で統一。
- 金額・国の設定を「保存」だけで終わらせず、公開状態を必ず確認。
- テストトラックは 内部 > クローズド > オープンの順で拡張し、段階的に QA を広げる。
- トランザクションのサーバー検証を導入し、アプリ単体では 状態を最終決定しない方針に。
付録:開発 PC 健康診断(週次ルーチン)
- Visual Studio Installer で SDK/ツールの更新確認(Android ビルドツールを含む)。
- 「ツール > オプション > 環境 > プレビュー機能」設定の棚卸し(アップデートで既定値が変わることがあります)。
- 不要な Android エミュレーター イメージの削除(容量・競合対策)。
- USB ケーブル/ポートの交換テスト(物理層トラブルの早期発見)。
- 社内ナレッジ(手順書・SKU リスト)を最新版に同期。
おわりに
デバッガが切断されると、ついアプリ側のロジックや課金 SDK を疑いがちです。しかし本件は IDE のプレビュー機能が直接の原因であるため、まずは環境設定を正すだけで解決できます。開発者が「コードを変えずに」障害を解けるのは生産性の観点で非常に重要です。この記事が、みなさんの .NET MAUI × Android 実機デバッグと課金検証の安定運用に役立てば幸いです。

コメント