Microsoft Edge WebView2 Runtime 148 prerelease では、WPFアプリに WebView2 を組み込んだ環境で「ウィンドウを閉じてもWPFプロセスが残る」問題に関係する修正がリリースノートに追加されています。結論から言うと、該当症状に悩んでいる WPF developers やデスクトップアプリ保守担当者は、いきなり本番反映するのではなく、Runtime 148 prerelease を検証環境で再現テストし、シャットダウン処理の実装と合わせて確認するのが現実的な対応です。
今回の更新は、派手な新機能というよりも、WPF + WebView2 アプリの安定性に直結する「終了時のプロセス残り」「Process-leak」「shutdown stability」に関わる実務向けの修正です。特に、業務アプリ、社内ツール、ランチャー、認証画面、HTMLベースの管理画面などで WebView2 を埋め込んでいる場合は、ユーザーから見えにくい不具合として残りやすいため、早めに確認する価値があります。
Microsoft Edge WebView2 Runtime 148 prerelease の注目点
Microsoft の WebView2 release notes では、Prerelease SDK 1.0.3965-prerelease, for Runtime 148 が 2026年4月13日リリースとして掲載されています。この prerelease SDK は、完全なAPI互換性のために Microsoft Edge version 148.0.3965.0 以上に同梱される WebView2 Runtime を必要とします。(Microsoft Learn)
今回、WPFアプリ開発者にとって特に重要なのは、Runtime-only の bug fix として次の修正が記載された点です。
WPF sample app で、ウィンドウを閉じたあとに WPF プロセスが残る問題を修正。
Microsoft Learn の記述は「WPF sample app」に対する修正として表現されています。つまり、すべてのWPFアプリにおけるプロセス残りを一括で解消する万能修正だと断定するのは避けるべきです。ただし、WebView2 を埋め込んだ WPF アプリで終了後に *.exe がタスクマネージャーに残る、再起動時に前回プロセスが邪魔をする、CIのUIテストが終了しない、といった症状がある場合は、検証対象に入れるべき更新です。(Microsoft Learn)
なぜ「WPFプロセスが残る」問題は見逃されやすいのか
WPFアプリで WebView2 を使っていると、画面上は正常に閉じたように見えても、裏側でアプリケーションプロセスや WebView2 関連プロセスが残ることがあります。ユーザーはすぐに気付かない一方で、運用では次のような問題につながります。
| 起きる問題 | 現場での影響 | よくある発見タイミング |
|---|---|---|
| アプリ終了後もプロセスが残る | メモリ使用量が増え続ける | 長時間利用後、端末が重くなったとき |
| アプリを再起動できない | 二重起動防止ロジックに引っかかる | ユーザーが「起動しない」と問い合わせたとき |
| 自動更新に失敗する | 実行中ファイルを置き換えられない | 配布ツールやインストーラー実行時 |
| UIテストが完了しない | CI/CDパイプラインが止まる | 自動テスト導入後 |
| サインイン状態やキャッシュが不安定になる | 再ログイン、画面読み込み失敗が増える | 認証画面をWebView2化した後 |
特に業務アプリでは、ユーザーがタスクマネージャーを確認することは多くありません。そのため、問い合わせとしては「アプリがたまに起動しない」「更新に失敗する」「PCを再起動すると直る」といった曖昧な形で届きます。WebView2 を使っている場合は、こうした症状を単なる環境依存として片付けず、終了処理とランタイムの両方から確認するのが重要です。
今回の修正をどう評価すべきか
今回の WebView2 Runtime 148 prerelease の修正は、WPFアプリの保守担当者にとって「すぐ本番投入する更新」というより、既知の終了安定性問題を切り分けるための検証材料として扱うのが安全です。
| 判断ポイント | 推奨アクション |
|---|---|
| WPF + WebView2 で終了後にプロセスが残る症状がある | Runtime 148 prerelease を検証環境で試す |
| 現在は問題が出ていない | 急いで切り替えず、次の安定版情報を追う |
| 自動テストでアプリ終了待ちが失敗する | テスト環境に prerelease を入れて比較する |
| 本番が厳格な業務端末・VDI・キオスク端末 | prerelease の直接配布は避け、再現確認に使う |
| WebView2 のクラッシュや異常終了も追跡したい | ProcessFailed イベントの変更点も確認する |
ポイントは、Runtime 148 prerelease だけで判断しないことです。WebView2 の終了問題は、ランタイム側の不具合だけでなく、アプリ側のライフサイクル管理、イベント購読、非同期処理、WPF Dispatcher の終了タイミングが絡むことがあります。
WPF + WebView2 アプリで確認すべき終了処理
WebView2 を埋め込んだ WPFアプリでは、ウィンドウを閉じるだけでなく、WebView2 コントロール、CoreWebView2、イベントハンドラー、バックグラウンド処理をきれいに解放できているかを確認します。
最低限チェックしたいポイント
| 確認項目 | 見るべき内容 |
|---|---|
| WebView2 コントロールの破棄 | Dispose() 可能なオブジェクトを適切に解放しているか |
| イベントハンドラー | NavigationCompleted、WebMessageReceived、ProcessFailed などを不要時に解除しているか |
| 非同期初期化 | EnsureCoreWebView2Async() 実行中にウィンドウが閉じられた場合の処理があるか |
| Dispatcher | バックグラウンドからUIスレッドへ投げた処理が残っていないか |
| タイマー | DispatcherTimer や System.Timers.Timer が停止されているか |
| 外部プロセス・IPC | named pipe、localhost通信、COM連携などが終了しているか |
| 二重起動防止 | 残留プロセスを前提にしたロックファイルやMutexが残っていないか |
WebView2 はブラウザーエンジンをアプリに組み込む仕組みです。HTMLを表示しているだけに見えても、内部ではレンダラープロセス、GPUプロセス、プロファイル、キャッシュ、Cookie、権限などが関係します。そのため、通常のWPF画面よりも終了時の後片付けを丁寧に設計する必要があります。
実装側でよくある落とし穴
たとえば、次のような実装はプロセス残りや終了遅延の原因になりやすいです。
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
await webView.EnsureCoreWebView2Async();
webView.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived;
}
このコード自体が悪いわけではありません。ただし、初期化中にウィンドウが閉じられた場合や、イベントを解除しないまま画面を閉じる場合、状態管理が複雑になります。実務では、少なくとも次のような観点を入れておくと安全です。
private bool _isClosing;
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
try
{
await webView.EnsureCoreWebView2Async();
if (_isClosing || webView.CoreWebView2 == null)
{
return;
}
webView.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived;
webView.CoreWebView2.ProcessFailed += CoreWebView2_ProcessFailed;
}
catch (ObjectDisposedException)
{
// ウィンドウ終了中の破棄で発生する場合があるため、必要に応じてログのみ残す
}
catch (Exception ex)
{
// 初期化失敗としてログに残す
LogError(ex);
}
}
private void Window_Closing(object sender, CancelEventArgs e)
{
_isClosing = true;
if (webView?.CoreWebView2 != null)
{
webView.CoreWebView2.WebMessageReceived -= CoreWebView2_WebMessageReceived;
webView.CoreWebView2.ProcessFailed -= CoreWebView2_ProcessFailed;
}
webView?.Dispose();
}
実際のコードでは、アプリの構成や使用している WebView2 SDK のバージョンに合わせて調整が必要です。重要なのは、画面を閉じる処理と WebView2 の非同期初期化・イベント購読が競合しないようにすることです。
Runtime 148 prerelease を検証する手順
該当症状がある場合は、次の順番で検証すると原因を切り分けやすくなります。
| 手順 | 作業内容 | 判断基準 |
|---|---|---|
| 1 | 現在の WebView2 Runtime と SDK バージョンを記録する | 比較できる状態を作る |
| 2 | 現行環境でプロセス残りを再現する | 再現条件を固定する |
| 3 | Runtime 148 prerelease 環境で同じ手順を実行する | 症状が消えるか確認する |
| 4 | アプリ側の終了処理ログを追加する | Closing、Closed、ProcessExit の順序を見る |
| 5 | UIテストや自動更新処理も確認する | ユーザー操作以外の終了パターンも見る |
| 6 | 本番投入可否を判断する | prerelease のため直接展開は慎重に扱う |
検証で重要なのは、「手元の開発PCで一度閉じられた」だけで判断しないことです。WebView2 関連の終了問題は、端末スペック、GPU設定、ユーザーデータフォルダー、認証状態、ネットワーク、リモートデスクトップ環境によって再現性が変わることがあります。
再現テストで見るべきシナリオ
最低でも次のパターンは確認しておくと、実運用での見落としを減らせます。
| シナリオ | 確認内容 |
|---|---|
| 起動直後に閉じる | WebView2 初期化中の終了で残らないか |
| ページ読み込み中に閉じる | ナビゲーション中の終了で残らないか |
| ログイン後に閉じる | Cookie、認証、リダイレクト後に残らないか |
| 複数ウィンドウを開いて閉じる | 最後のウィンドウ終了後にプロセスが消えるか |
| アプリ内更新後に再起動する | 旧プロセスが邪魔しないか |
| 自動テストから起動・終了する | CI環境で待機状態にならないか |
ProcessFailed イベントの変更点も見逃せない
Runtime 148 prerelease では、WPFプロセス残りの修正だけでなく、ProcessFailed イベントに関する変更も含まれています。これまで CoreWebView2ProcessFailedEventArgs.Reason が Unexpected として返していた複数の終了シナリオについて、feature flag を有効にした場合に NormalExit、AbnormalExit、IntegrityFailure といったより細かい理由を返せるようになります。(Microsoft Learn)
この変更は、WebView2 を使うデスクトップアプリの保守にとって重要です。なぜなら、プロセス終了の原因を「クラッシュらしい」「原因不明」と扱うのではなく、通常終了、異常終了、コード整合性の問題として分類しやすくなるからです。
| 新しい理由 | 実務での見方 |
|---|---|
NormalExit | 正常終了。過剰なエラー通知を出さない判断に使える |
AbnormalExit | 異常終了。ログ収集や再読み込みの対象にする |
IntegrityFailure | DLLや実行環境の整合性問題を疑う。端末固有の調査が必要 |
ただし、Microsoft のリリースノートでは、この granular reason の feature flag は release 148 と 149 では既定で無効、release 150 から既定で有効になる予定と説明されています。事前検証する場合は、次のような追加ブラウザー引数を使います。(Microsoft Learn)
set WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS=--enable-features=msWebView2GranularProcessFailedReason
本番アプリで ProcessFailed の値を固定的に判定している場合は、将来の release 150 以降で挙動が変わる可能性があります。Unexpected だけを前提にしたログ分類や復旧処理を実装している場合は、早めに見直しておくと安全です。
本番アプリへ反映する前の判断基準
WebView2 Runtime 148 prerelease は、問題を抱える開発チームにとって魅力的な検証対象です。一方で、prerelease をそのまま本番配布するかは慎重に判断する必要があります。
反映を急いでもよいケース
次のような場合は、検証優先度を高くしてよいでしょう。
- アプリを閉じてもWPFプロセスが頻繁に残る
- 残留プロセスが原因で自動更新や再起動に失敗している
- VDI、RDS、キオスク端末などでプロセス残りが運用障害になっている
- UI自動テストでアプリ終了待ちが不安定になっている
- WebView2 を使う画面の終了時だけ問題が起きる
この場合でも、最初に行うべきことは本番展開ではなく、同じ再現手順で Runtime 147 以前と Runtime 148 prerelease を比較することです。差が明確に出るなら、次の安定版への追随計画を立てやすくなります。
慎重に様子を見るべきケース
一方で、次のような場合は無理に prerelease を配布する必要はありません。
- 現在の安定版で終了問題が出ていない
- WebView2 を重要な業務フローの中心で使っている
- 端末管理ポリシー上、prerelease ランタイムの導入が難しい
- 検証環境と本番環境の差が大きい
- 問題がWPF側、アプリ側、外部連携側にありそう
特に業務端末では、WebView2 Runtime が他のアプリにも影響する可能性があります。自社アプリだけでなく、同じ端末上で WebView2 を利用する別アプリの動作確認も必要になる場合があります。
WPFアプリ保守担当者が今やるべきこと
今回の更新を受けて、WPF developers and desktop app maintainers がすぐに行うべきことは、次の3つです。
まず現象をログで可視化する
「プロセスが残ることがある」という報告だけでは、ランタイムの問題かアプリ側の問題か判断できません。最低限、次のタイミングでログを残します。
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
LogInfo("Application startup");
}
protected override void OnExit(ExitEventArgs e)
{
LogInfo("Application exit");
base.OnExit(e);
}
Window 側でも、Closing、Closed、WebView2 初期化開始・完了、ProcessFailed の発生を記録します。ログには、日時、スレッドID、画面名、URL、WebView2 Runtime バージョンを含めると調査が楽になります。
ユーザーデータフォルダーを確認する
WebView2 の UserDataFolder を明示している場合、アプリ終了時のキャッシュやプロファイル状態が影響することがあります。複数インスタンスで同じフォルダーを使っていないか、更新時に削除・移動しようとしていないか、端末の権限で書き込めるかを確認します。
特に社内アプリでは、次のような設定が問題を複雑にします。
| 設定・環境 | 注意点 |
|---|---|
| roaming profile | ユーザーデータの同期遅延で終了が重くなる場合がある |
| ネットワークドライブ | キャッシュやプロファイルの読み書きが不安定になりやすい |
| 権限が厳しい端末 | WebView2 のデータ保存に失敗する可能性がある |
| 複数アプリで同一フォルダー共有 | ロックや競合の原因になる |
| 自動削除スクリプト | 終了処理と競合する可能性がある |
終了時の「強制終了頼み」を避ける
プロセスが残るからといって、最後に Process.Kill() で自分自身や関連プロセスを落とす実装は、原則として避けるべきです。一時的に症状を隠せても、データ破損、ログ欠落、認証状態の不整合、更新失敗の原因になります。
現実的には、次の順で対処します。
- WebView2 とWPFの終了処理を整理する
- イベント購読と非同期処理の競合をなくす
- 現行Runtimeと Runtime 148 prerelease で比較する
ProcessFailedのログを追加する- 安定版への反映タイミングを決める
どうしても業務上の暫定回避が必要な場合でも、強制終了は最後の手段にし、対象プロセス、条件、ログ出力、ユーザー影響を明確にしておくべきです。
開発チーム向けの検証チェックリスト
以下のチェックリストを使うと、今回の WebView2 Runtime 148 prerelease を安定性更新として評価しやすくなります。
| チェック | 内容 | 完了条件 |
|---|---|---|
| バージョン確認 | SDK、Runtime、Edge channel を記録 | 比較表に残す |
| 再現手順作成 | 終了後にプロセスが残る操作を固定 | 誰が実行しても再現できる |
| 現行環境テスト | 現在のRuntimeでプロセス残りを確認 | Before の証跡を取得 |
| prerelease テスト | Runtime 148 prerelease で同条件を確認 | After の証跡を取得 |
| ログ追加 | 起動、初期化、終了、ProcessFailed を記録 | 原因分類できる |
| 複数端末確認 | 開発PC以外でも試す | 端末依存を切り分ける |
| 配布判断 | 本番投入、待機、追加調査を決める | リリース判断を文書化 |
このチェックリストの目的は、単に「新しいRuntimeで直ったか」を見ることではありません。今後の安定版更新や別のWebView2不具合に備えて、検証の型を作ることです。
今回の更新をどう伝えるべきか
社内やチームに共有する場合は、「WebView2 Runtime 148 prerelease でWPF終了時のプロセス残りが完全解消」と書くのは避けた方が安全です。Microsoft のリリースノート上は、WPF sample app に関する修正として記載されています。(Microsoft Learn)
実務向けには、次のような表現が適切です。
Microsoft Edge WebView2 Runtime 148 prerelease のリリースノートに、WPF sample app でウィンドウを閉じた後にWPFプロセスが残る問題の修正が追加された。WebView2 を埋め込んだWPFアプリで類似の終了問題がある場合は、検証環境で再現比較を行う。
この表現なら、更新内容を過大評価せず、開発チームが次に取るべき行動も明確になります。
まとめ:Runtime 148 prerelease はWPF + WebView2の終了安定性を見直す好機
Microsoft Edge WebView2 Runtime 148 prerelease の更新では、WPF sample app においてウィンドウを閉じた後に WPF プロセスが残る問題の修正が記載されました。WPFアプリに WebView2 を組み込んでいる開発者にとって、これは「終了処理」「プロセスリーク」「shutdown stability」を見直すよいタイミングです。
ただし、prerelease は本番即投入ではなく、検証環境での比較に使うのが基本です。まずは現在のRuntimeで症状を再現し、Runtime 148 prerelease で改善するか確認しましょう。あわせて、WebView2 の破棄、イベント解除、非同期初期化、ProcessFailed のログ収集を整理すれば、今回の修正に依存しすぎない安定したWPFアプリ運用につながります。
次に取るべき行動は明確です。WebView2 を組み込んだWPFアプリで終了後のプロセス残りが疑われるなら、現在のバージョンと再現手順を記録し、Runtime 148 prerelease で同じ条件を検証してください。その結果をもとに、アプリ側の終了処理を直すべきか、次の安定版Runtimeを待つべきかを判断するのが、もっとも安全で実務的な進め方です。

コメント