WebView2 アプリで ProcessFailed を監視しているなら、いま確認すべきポイントは Reason == Unexpected を前提にした実装を見直すこと です。Microsoft Edge WebView2 Runtime 148 prerelease 向けの SDK 1.0.3965-prerelease では、これまで同じ Unexpected として扱われていた「正常終了」「異常終了」「コード整合性エラー」を、NormalExit、AbnormalExit、IntegrityFailure として判別できるようになりました。148 と 149 では既定で無効ですが、150 から既定で有効になる予定のため、Desktop app developers using WebView2 は早めにテストしておくべき変更です。(Microsoft Learn)
Microsoft Edge WebView2 Runtime 148 prereleaseで何が変わったのか
2026年4月18日時点で注目すべき更新は、Microsoft が WebView2 SDK のリリースノートに追加した ProcessFailed イベントの失敗理由を細かく返す変更 です。対象は Prerelease SDK 1.0.3965-prerelease, for Runtime 148 で、リリース日は 2026年4月13日、完全な API 互換性には Microsoft Edge 148.0.3965.0 以降に含まれる WebView2 Runtime が必要とされています。(Microsoft Learn)
ProcessFailed は、WebView2 に関連するレンダラー、GPU、ユーティリティなどのプロセスで問題が起きたときに発生するイベントです。従来も復旧処理や診断ログに使えましたが、今回の変更により、CoreWebView2ProcessFailedEventArgs.Reason が返す情報の粒度が上がります。
変更前は、次の3つがすべて Unexpected として返されていました。
| シナリオ | 変更前の Reason | 変更後の Reason |
|---|---|---|
| プロセスが終了コード 0 で正常終了した | Unexpected | NormalExit |
| クラッシュや強制終了ではないが、0以外の終了コードで異常終了した | Unexpected | AbnormalExit |
| DLL などが Windows Code Integrity の検証に失敗し、OS によって終了させられた | Unexpected | IntegrityFailure |
この変更は、msWebView2GranularProcessFailedReason フィーチャーフラグが有効な場合に反映されます。Microsoft の案内では、Runtime 148 と 149 ではこのフラグは既定で無効、Runtime 150 から既定で有効になる予定です。(Microsoft Learn)
なぜbreaking changeなのか
一見すると、これは単なる診断情報の改善に見えます。しかし、既存の WebView2 アプリにとっては 実行時の分岐結果が変わる ため、breaking change として扱う必要があります。
たとえば、次のような実装は影響を受けやすい典型例です。
if (e.Reason == CoreWebView2ProcessFailedReason.Unexpected)
{
ShowCrashDialog();
ReloadWebView();
}
このコードは、これまで Unexpected に含まれていたケースを一括処理しています。ところが新しい挙動では、同じ状況の一部が NormalExit、AbnormalExit、IntegrityFailure として返る可能性があります。その結果、従来実行されていた復旧処理、ログ出力、ユーザー通知、監視アラートが動かなくなることがあります。
特に注意すべきなのは、次のようなコードです。
| 影響を受けやすい実装 | 起きやすい問題 |
|---|---|
Unexpected のみをエラー扱いしている | AbnormalExit や IntegrityFailure を見逃す |
switch に default がない | 新しい enum 値を処理できない |
| テレメトリの集計値を固定リストで検証している | 未知の値として破棄、または集計エラーになる |
すべての ProcessFailed をクラッシュとして通知している | NormalExit でも誤ってクラッシュ表示する |
| 旧 SDK の enum 名だけを前提にしている | Runtime 側で新しい数値が返ったときに分岐漏れが起きる |
Microsoft の GitHub 告知でも、ProcessFailed を処理し Reason を確認しているアプリ、特に default のない switch や if 分岐を持つアプリは更新が必要になる可能性があると説明されています。(GitHub)
NormalExit、AbnormalExit、IntegrityFailureの違い
今回追加された3つの値は、単に名前が増えたわけではありません。障害対応の優先順位を変えるための情報です。
Reason | 意味 | 実務での扱い |
|---|---|---|
NormalExit | プロセスが終了コード 0 で正常終了した | まずは情報ログ扱い。即クラッシュ扱いにしない |
AbnormalExit | 0以外の終了コードで終了したが、クラッシュや強制終了ではない | ExitCode、ProcessFailedKind、再現条件を記録し、必要に応じて復旧 |
IntegrityFailure | Windows Code Integrity の検証失敗により OS がプロセスを終了した | DLL、署名、配布物、セキュリティ製品や企業ポリシーの影響を調査 |
CoreWebView2ProcessFailedReason の API リファレンスでは、NormalExit は終了コード 0 の正常な終了、AbnormalExit は0以外の終了コードによる異常終了、IntegrityFailure は DLL が Windows Code Integrity verification に失敗したようなコード整合性エラーによる OS 側の終了として説明されています。(Microsoft Learn)
NormalExitは「クラッシュ」と決めつけない
ProcessFailed が発生したからといって、必ずしもユーザーに「WebView2 がクラッシュしました」と表示すべきではありません。NormalExit は、プロセスが終了コード 0 で終了したことを示します。
実務では、まず次のように扱うのが安全です。
| 判断ポイント | 推奨アクション |
|---|---|
| UI が継続利用できる | ユーザー通知は出さず、情報ログに残す |
| 特定の画面だけ再描画が必要 | 対象 WebView の状態を確認し、必要なら reload |
| 同じ環境で頻発する | ProcessFailedKind と組み合わせて原因を調査 |
| アプリ終了時や画面破棄時に発生 | ライフサイクル上の自然な終了か確認 |
特に業務アプリでは、不要なクラッシュ通知はサポート問い合わせを増やします。NormalExit は「失敗イベント内で通知された正常終了」として、クラッシュ系のアラートとは分けて集計するのがおすすめです。
AbnormalExitは終了コードとプロセス種別をセットで見る
AbnormalExit は、0以外の終了コードでプロセスが終了したが、クラッシュやタスクマネージャーからの kill とは区別されるケースです。ここで重要なのは、Reason だけで復旧方針を決めないことです。
WebView2 のプロセス関連イベントでは、ProcessFailedKind が「どの種類のプロセスで、どのような失敗が起きたか」を表し、Reason が「原因のカテゴリ」を表します。Microsoft のドキュメントでも、ProcessFailedKind と Reason を使って失敗を識別できると説明されています。(Microsoft Learn)
たとえば同じ AbnormalExit でも、対象がメインフレームのレンダラープロセスなのか、GPU プロセスなのかで対応は変わります。
ProcessFailedKind の例 | 対応の考え方 |
|---|---|
RenderProcessExited | 画面がエラーページになる可能性があるため、Reload または WebView 再作成を検討 |
FrameRenderProcessExited | 影響範囲がサブフレームなら、該当フレームの情報を記録 |
GpuProcessExited | 多くの場合は自動復旧されるため、頻度と環境差を監視 |
UtilityProcessExited | 音声・動画・補助機能への影響を確認し、必要に応じて情報ログ化 |
Microsoft のプロセス関連イベントの説明では、レンダラープロセス終了時はコンテンツがエラーページに置き換わる可能性があり、メインフレームが影響を受けた場合は Reload または WebView2 コントロールの再作成が選択肢になるとされています。GPU プロセスやユーティリティプロセスの終了は自動復旧される場合があり、継続的な問題の把握にログ収集が有効です。(Microsoft Learn)
IntegrityFailureは配布物とセキュリティ環境を調べる
IntegrityFailure は、通常のレンダリング障害とは調査の方向が異なります。これは OS がコード整合性の問題を検出し、プロセスを終了させたことを示します。
このケースでは、単に reload しても根本解決にならない可能性があります。次の観点で確認してください。
| 確認項目 | 見るべきポイント |
|---|---|
| DLL の署名 | 自社 DLL、サードパーティ DLL、ネイティブ拡張が正しく署名されているか |
| 配布パッケージ | インストーラーや更新差分で DLL が破損していないか |
| セキュリティ製品 | EDR、ウイルス対策、アプリ制御ポリシーが DLL 読み込みを妨げていないか |
| 企業ポリシー | WDAC などのコード実行制御が影響していないか |
| 端末差 | 特定の顧客環境、OS ビルド、管理ポリシー配下でのみ起きていないか |
CoreWebView2ProcessFailedEventArgs には、失敗したプロセスの終了コードや FailureSourceModulePath など、診断に使えるプロパティがあります。Microsoft の API リファレンスでは、Code Integrity check に失敗した場合、FailureSourceModulePath が読み込みを阻止されたファイルのフルパスを返すと説明されています。(Microsoft Learn)
既存アプリでまず確認すべきコード
最初に見るべきなのは、CoreWebView2.ProcessFailed のイベントハンドラーです。検索対象は次のキーワードです。
ProcessFailed
CoreWebView2ProcessFailedEventArgs
ProcessFailedKind
CoreWebView2ProcessFailedReason
Reason
Unexpected
特に、Unexpected を中心にした条件分岐がある場合は優先的に見直します。
避けたい実装
switch (e.Reason)
{
case CoreWebView2ProcessFailedReason.Unexpected:
ReloadWebView();
break;
case CoreWebView2ProcessFailedReason.Crashed:
ShowCrashDialog();
break;
}
この実装には default がありません。今後 NormalExit、AbnormalExit、IntegrityFailure が返ったときに、どの処理にも入らない可能性があります。
また、Unexpected を「原因不明のクラッシュ」として扱っている場合も要注意です。今回の変更により、以前 Unexpected に含まれていた一部のシナリオが別の値として返るため、ログやアラートの意味が変わります。
望ましい実装例
実装では、復旧判断は ProcessFailedKind、原因分類は Reason、調査情報は ExitCode や FailureSourceModulePath というように役割を分けると保守しやすくなります。
using Microsoft.Web.WebView2.Core;
webView.CoreWebView2.ProcessFailed += (_, e) =>
{
LogWebView2ProcessFailure(
kind: e.ProcessFailedKind,
reason: e.Reason,
exitCode: e.ExitCode,
processDescription: e.ProcessDescription,
failureSourceModulePath: e.FailureSourceModulePath
);
switch (e.Reason)
{
case CoreWebView2ProcessFailedReason.NormalExit:
// 正常終了。ユーザー向けのクラッシュ通知は出さず、必要に応じて情報ログに留める。
break;
case CoreWebView2ProcessFailedReason.AbnormalExit:
// 異常終了。ProcessFailedKind と ExitCode を見て、reload または再作成を判断する。
RecoverByProcessKind(e.ProcessFailedKind);
break;
case CoreWebView2ProcessFailedReason.IntegrityFailure:
// コード整合性エラー。阻止された DLL などを診断情報として収集する。
ReportIntegrityFailure(e.FailureSourceModulePath, e.ExitCode);
break;
case CoreWebView2ProcessFailedReason.Crashed:
case CoreWebView2ProcessFailedReason.OutOfMemory:
case CoreWebView2ProcessFailedReason.Unresponsive:
case CoreWebView2ProcessFailedReason.Terminated:
case CoreWebView2ProcessFailedReason.LaunchFailed:
RecoverByProcessKind(e.ProcessFailedKind);
break;
default:
// 将来の enum 追加に備える。未知の値でもログを残し、最低限の復旧経路に流す。
RecoverByProcessKind(e.ProcessFailedKind);
break;
}
};
ポイントは、新しい enum 値を個別に扱いつつ、将来の追加値にも備えて default を残すこと です。WebView2 Runtime は継続的に更新されるため、未知の Reason が来ても落ちない設計にしておくと、安定版 Runtime の更新にも強くなります。
148・149のうちにテストする方法
Runtime 148 と 149 では、msWebView2GranularProcessFailedReason は既定で無効です。つまり、何もしなければ従来どおり Unexpected が返るため、本番環境で即座に挙動が変わるわけではありません。
ただし、Runtime 150 で既定有効になる前に、テスト環境でフラグを有効化して挙動を確認しておく必要があります。
コマンドプロンプトでは、アプリ起動前に次のように設定します。
set WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS=--enable-features=msWebView2GranularProcessFailedReason
MyApp.exe
PowerShell では次のように実行できます。
$env:WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS="--enable-features=msWebView2GranularProcessFailedReason"
.\MyApp.exe
Microsoft のリリースノートでも、この環境変数を使って WebView2 アプリの挙動を検証する方法が案内されています。(Microsoft Learn)
テスト時に見るべき項目
単にアプリが起動するかを見るだけでは不十分です。ProcessFailed の変更は、障害時・終了時・セキュリティ制御時の挙動に関わるため、次の観点で確認します。
| テスト項目 | 確認内容 |
|---|---|
| イベントハンドラー | NormalExit、AbnormalExit、IntegrityFailure、未知の値で例外が出ないか |
| UI 表示 | 正常終了や自動復旧可能な終了で、クラッシュダイアログを出していないか |
| ログ | Reason、ProcessFailedKind、ExitCode、ProcessDescription を記録しているか |
| 監視 | 新しい enum 値がダッシュボードやアラートで欠損しないか |
| 復旧 | レンダラー終了時に reload、WebView 再作成、画面遷移のどれが適切か |
| サポート導線 | IntegrityFailure 時に調査に必要な DLL パスや端末情報を取得できるか |
テスト環境では、Reason の文字列だけでなく数値もログに残しておくと、SDK 更新前後の比較がしやすくなります。
診断ログに追加したいフィールド
今回の変更を活かすには、Reason だけを記録するのではなく、周辺情報も一緒に保存することが重要です。WebView2 の ProcessFailed イベントは診断や監視に使える詳細情報を提供し、クラッシュ時には FailureReportFolderPath 配下のダンプが原因調査に役立つ場合があります。(Microsoft Learn)
最低限、次の項目をログに含めると実務で追跡しやすくなります。
| フィールド | 目的 |
|---|---|
Reason | 失敗理由の分類。今回の変更で最も重要 |
ProcessFailedKind | どのプロセス種別で起きたかを判断 |
ExitCode | 異常終了やコード整合性エラーの切り分け |
ProcessDescription | ユーティリティプロセスなどの識別 |
FailureSourceModulePath | IntegrityFailure 時に問題の DLL などを特定 |
| Runtime version | 特定の Runtime 更新後に増えたか確認 |
| SDK version | enum 名や API 参照の差分を確認 |
| OS version / architecture | 端末差や企業環境差の切り分け |
| App version | 配布物の差し替えや更新失敗の追跡 |
| User data folder | プロファイル破損や複数環境の切り分け |
ログ設計では、Reason を固定の列挙値だけでバリデーションしないことも大切です。将来の WebView2 更新で enum が追加されても取り込めるように、文字列と数値の両方を保存する、未知の値を UnknownFutureValue のようなカテゴリで扱う、といった設計が安全です。
ユーザー向けメッセージはReasonごとに変える
Desktop app developers using WebView2 が見落としがちなのは、診断情報の変更がユーザー体験にも影響する点です。すべての ProcessFailed を「ブラウザー部分がクラッシュしました」と表示すると、NormalExit や自動復旧可能な GPU プロセス終了でも不要な不安を与えます。
実装では、次のように表示方針を分けると現実的です。
Reason | ユーザー向け表示の考え方 |
|---|---|
NormalExit | 原則表示しない。画面に影響がある場合のみ再読み込み案内 |
AbnormalExit | 画面復旧が必要な場合に「表示を再読み込みします」と案内 |
IntegrityFailure | 「必要なコンポーネントを読み込めませんでした」とし、管理者・サポートへの連絡導線を出す |
Crashed | クラッシュとして扱い、再読み込みまたは再起動を案内 |
OutOfMemory | メモリ不足の可能性を示し、他アプリ終了や再起動を案内 |
Unresponsive | 待機、再読み込み、ページ移動の選択肢を提示 |
エンドユーザーに IntegrityFailure や Code Integrity といった内部用語をそのまま出す必要はありません。サポートログには詳細を残し、画面上は「必要なコンポーネントを読み込めない」「管理ポリシーまたはセキュリティ設定の影響を受けている可能性がある」といった表現にすると、問い合わせ対応につなげやすくなります。
移行チェックリスト
Runtime 150 で既定有効になる前提で、次の順番で対応すると無理がありません。
| 優先度 | 対応内容 | 目的 |
|---|---|---|
| 高 | ProcessFailed ハンドラーを検索する | 影響範囲を洗い出す |
| 高 | switch / if に default または未知値処理を追加する | 新しい enum 値で処理漏れを防ぐ |
| 高 | NormalExit をクラッシュ扱いしない | 誤通知・誤アラートを減らす |
| 高 | AbnormalExit と IntegrityFailure のログ項目を追加する | 障害調査の精度を上げる |
| 中 | テレメトリのスキーマを確認する | 新しい値の欠損や集計失敗を防ぐ |
| 中 | テスト環境でフラグを有効化する | Runtime 150 前に挙動差を確認する |
| 中 | サポート手順書を更新する | 顧客環境での調査を早くする |
| 低 | UI 文言を Reason ごとに調整する | 不要なクラッシュ表示を減らす |
今回の変更は、WebView2 アプリの復旧処理を壊すためのものではなく、これまで Unexpected に丸められていた情報を開発者が正しく使えるようにするための変更です。だからこそ、単に enum を追加するだけでなく、ログ、監視、ユーザー通知、サポート運用まで含めて見直す価値があります。
まとめ:Runtime 150前にProcessFailedの分岐を更新する
Microsoft Edge WebView2 Runtime 148 prerelease の ProcessFailed 変更では、Reason に NormalExit、AbnormalExit、IntegrityFailure が追加され、WebView2 アプリは正常終了、異常終了、コード整合性エラーを区別できるようになります。148 と 149 ではフラグで事前検証し、150 で既定有効になる前に、Unexpected 前提の実装を更新しておくのが安全です。
まずはコードベースから ProcessFailed と CoreWebView2ProcessFailedReason.Unexpected を検索し、default のない分岐、クラッシュ扱いの固定ロジック、テレメトリの固定 enum 定義を確認してください。次に、msWebView2GranularProcessFailedReason を有効にしたテスト環境で、ログと復旧処理が期待どおり動くかを検証します。これだけでも、Runtime 更新後の「突然 WebView2 の障害ログが変わった」「クラッシュ通知が出ない」「セキュリティ環境でだけ起動しない」といった調査コストを大きく減らせます。

コメント