WebView2を組み込んだWPFアプリが、外部モニターの取り外しやドッキングステーションの切断をきっかけにクラッシュする場合、アプリ独自の例外処理ではなく、WebView2のComposition経路に起因する不具合の可能性があります。
Microsoftは、Composition制御を使用するWPFアプリで、ディスプレイトポロジー変更時にクラッシュする問題を修正済みです。 修正は2026年8月3日公開のWebView2 SDK 1.0.4181-prereleaseで案内されており、対応するWebView2 Preview Runtimeは152.0.4181.0以上です。まずSDKとRuntimeを組み合わせて更新し、モニター切断を含む実機テストを行う必要があります。(Microsoft Learn)
ただし、対象はすべてのWPF版WebView2ではありません。主にWebView2CompositionControlやCoreWebView2CompositionControllerを使用しているアプリが該当します。また、Runtime 152.0.4181.0は早期検証用のPreview Runtimeであるため、確認せず全利用者へ一斉配布するのではなく、検証環境から段階的に展開することが重要です。(Microsoft Learn)
モニター接続変更でWebView2 WPFアプリが落ちる問題を修正
Microsoftが公開した修正内容は次のとおりです。
| 確認項目 | 内容 |
|---|---|
| 修正公開日 | 2026年8月3日 |
| WebView2 SDK | 1.0.4181-prerelease |
| 対応Runtime | WebView2 Preview Runtime 152.0.4181.0以上 |
| 対象 | Composition制御を使用するWPFアプリ |
| 発生契機 | ディスプレイトポロジーの変更 |
| Microsoftの対応 | クラッシュ問題を修正済み |
Microsoftの表現では、SDKは「Prerelease」、Runtimeは「Preview Runtime」です。似た名称ですが、SDKと実際のWebコンテンツを動かすRuntimeは別のコンポーネントです。
また、クラッシュ修正の記載はSDKリリースノート側にありますが、修正がSDK側だけなのか、Runtime側も含むのかという内部実装の詳細は公開されていません。そのため、SDKだけ、またはRuntimeだけを更新するのではなく、対応する組み合わせで更新して再ビルドするのが安全です。Microsoftも、WebView2の変更によってSDK、Runtime、または両方の更新が必要になる場合があると説明しています。(Microsoft Learn)
自分のWPFアプリが対象か確認する
最初に、アプリがComposition制御を使用しているか確認します。
WebView2CompositionControlを使っている
XAMLに次のような記述がある場合は、今回の修正対象に該当する可能性が高いと判断できます。
<wv2:WebView2CompositionControl
x:Name="webView"
Source="https://example.com" />
コード上で次のクラスを生成している場合も同様です。
var webView = new WebView2CompositionControl();
WebView2CompositionControlは、WebView2の表示内容をWPFのImage経由で描画するビジュアルホスティング用コントロールです。内部では画面内容の取得にGraphicsCaptureSessionを使用します。(Microsoft Learn)
CoreWebView2CompositionControllerを直接使っている
独自のホスト実装で、次のようなAPIを呼び出している場合も対象候補です。
var controller =
await environment.CreateCoreWebView2CompositionControllerAsync(parentWindow);
CoreWebView2CompositionControllerは、通常のCoreWebView2Controllerが持つ機能に加えて、Compositionベースの描画機能を提供します。(Microsoft Learn)
通常のWebView2コントロールだけを使っている
次の標準コントロールだけを使用している場合、今回のリリースノートに書かれた対象と完全には一致しません。
<wv2:WebView2 x:Name="webView" />
標準のWebView2でもモニター変更時に落ちるのであれば、同じ問題だと決めつけず、例外コード、Runtimeバージョン、GPUドライバー、アプリ独自処理を個別に確認してください。
| 実装 | 今回の問題との関連 |
|---|---|
WebView2CompositionControl | 関連する可能性が高い |
CoreWebView2CompositionController | 関連する可能性が高い |
標準のWebView2 | リリースノート上の直接対象とは断定できない |
| WebView2を使用していない | 別原因 |
発生条件と典型的な症状
公開された再現報告では、.NET Framework 4.8のWPFアプリでWebView2CompositionControlを表示し、アプリウィンドウがある外部モニターを切断すると、WPFのレンダースレッドでエラーが発生しました。
報告されている代表的な例外は次のものです。
System.Runtime.InteropServices.COMException (0x88980406)
UCEERR_RENDERTHREADFAILURE
グローバル例外ハンドラーがないアプリではプロセスがクラッシュし、DispatcherUnhandledExceptionで例外を処理済みにすると、プロセスは残ってもWebView2の描画が停止したまま復旧しないケースが報告されています。(GitHub)
同じ報告では、次の条件が記録されています。
| 項目 | 再現報告の条件 |
|---|---|
| フレームワーク | .NET Framework 4.8 |
| WebView2 SDK | 1.0.4078.44 |
| Runtime | 1.0.4078.44と記録 |
| OS | Windows 11、ビルド26100 |
| 構成 | 複数モニター |
| 操作 | アプリを表示しているモニターを切断 |
| 結果 | フリーズまたはクラッシュ |
この報告では.NET 8を対象にした同等のアプリでは再現しなかったとされています。ただし、これは特定の再現環境における結果です。「.NET 8なら必ず発生しない」と一般化することはできません。(GitHub)
テストすべきモニター変更操作
「ディスプレイトポロジーの変更」には、単にウィンドウを別モニターへ移動する操作ではなく、Windowsが有効なディスプレイ構成を組み替える操作が含まれます。Windowsのディスプレイ構成では、複製、拡張、レイアウト、解像度、向きなどが管理されます。(Microsoft Learn)
少なくとも、次の操作をテストしてください。
| テスト操作 | 優先度 | 確認内容 |
|---|---|---|
| アプリを表示している外部モニターを取り外す | 必須 | クラッシュ、フリーズ、描画停止が起きないか |
| USB-C・Thunderboltドックを切断する | 必須 | 内蔵画面へ正常に移動・再描画できるか |
Windows+Pで「拡張」から「PC画面のみ」へ変更する | 高 | WebView2が操作可能な状態を維持するか |
| Windowsの設定でモニターを無効化する | 高 | 例外や画面停止が起きないか |
| モニターを再接続する | 高 | 再描画、入力、ナビゲーションが復旧するか |
| 異なるDPIのモニターへ構成を切り替える | 中 | 表示倍率、クリック位置、文字描画が正常か |
例外処理だけでは解決しない理由
UCEERR_RENDERTHREADFAILUREは、WPFのレンダリング処理が正常に継続できなくなったことを示します。本件ではCompositionベースのWebView2描画と、モニター構成変更時のグラフィックスデバイス再構成が関係していると考えられます。
ただし、Microsoftはリリースノートで詳細な根本原因を公開していません。アプリ側でGPUデバイスロストやWPF内部処理を推測し、独自修正を加えるよりも、Microsoftが修正したWebView2を適用するのが基本です。
次のようにすべての例外を処理済みにする方法は、修正にはなりません。
Application.Current.DispatcherUnhandledException += (_, e) =>
{
e.Handled = true;
};
この処理ではアプリが終了しなくなる場合がありますが、WebView2の描画セッションが壊れたまま残り、画面が永久に停止する可能性があります。さらに、本来終了させるべき別の重大な例外まで握りつぶしてしまいます。公開された再現報告でも、例外を処理済みにした後にコントロールが復旧しない症状が確認されています。(GitHub)
WebView2 WPFのモニター変更クラッシュを修正する手順
現在のSDKバージョンを確認する
プロジェクトファイルでMicrosoft.Web.WebView2のバージョンを確認します。
<ItemGroup>
<PackageReference
Include="Microsoft.Web.WebView2"
Version="1.0.4078.44" />
</ItemGroup>
Visual Studioを使用している場合は、次の場所でも確認できます。
- ソリューションエクスプローラーでプロジェクトを右クリックする
- 「NuGetパッケージの管理」を開く
- 「インストール済み」を選択する
Microsoft.Web.WebView2のバージョンを確認する
SDKを1.0.4181-prereleaseへ更新する
SDKスタイルのプロジェクトでは、次のコマンドを使用できます。
dotnet add package Microsoft.Web.WebView2 --version 1.0.4181-prerelease
Visual Studioのパッケージマネージャーコンソールでは、次を実行します。
Install-Package Microsoft.Web.WebView2 -Version 1.0.4181-prerelease
プロジェクトファイルへ直接記述する場合は次のとおりです。
<ItemGroup>
<PackageReference
Include="Microsoft.Web.WebView2"
Version="1.0.4181-prerelease" />
</ItemGroup>
NuGetでは、Microsoft.Web.WebView2 1.0.4181-prereleaseが2026年8月3日公開のパッケージとして提供されています。(NuGet)
更新後は、ソリューションをクリーンしてから再ビルドしてください。配布フォルダーを上書き更新している場合は、以前のMicrosoft.Web.WebView2.*.dllが残っていないことも確認します。
Preview Runtime 152.0.4181.0以上でテストする
SDK 1.0.4181-prereleaseは、完全な互換性を得るためにMicrosoft Edgeバージョン152.0.4181.0以降に含まれるWebView2 Runtimeを必要とします。(Microsoft Learn)
Preview Runtimeは、Microsoft EdgeのBeta、Dev、Canaryなどのプレビューチャネルを利用して検証できます。Microsoftは、Prerelease SDKの早期テストではCanaryを推奨しています。(Microsoft Learn)
検証用ビルドでプレビューチャネルを優先する例は次のとおりです。
using Microsoft.Web.WebView2.Core;
var options = new CoreWebView2EnvironmentOptions
{
ReleaseChannels =
CoreWebView2ReleaseChannels.Canary |
CoreWebView2ReleaseChannels.Dev |
CoreWebView2ReleaseChannels.Beta,
ChannelSearchKind = CoreWebView2ChannelSearchKind.LeastStable
};
var environment = await CoreWebView2Environment.CreateAsync(
browserExecutableFolder: null,
userDataFolder: null,
options: options);
await webView.EnsureCoreWebView2Async(environment);
LeastStableを指定すると、Canary、Dev、Betaの順に検索されます。ReleaseChannelsで指定したチャネルが端末にインストールされていない場合は、環境作成が失敗するため、例外処理も実装してください。(Microsoft Learn)
この設定をそのまま本番アプリへ入れると、利用者の端末でもプレビューチャネルを優先する可能性があります。検証専用のビルド設定や環境変数で切り替えるのが安全です。
実際に使われたRuntimeバージョンを記録する
端末に複数のWebView2 RuntimeやEdgeチャネルが入っている場合、インストール済み一覧を見るだけでは、アプリがどのRuntimeを選択したか判断できません。
WebView2の初期化後に、実際に選択されたバージョンを記録します。
await webView.EnsureCoreWebView2Async(environment);
string runtimeVersion =
webView.CoreWebView2.Environment.BrowserVersionString;
System.Diagnostics.Debug.WriteLine(
$"WebView2 Runtime: {runtimeVersion}");
最低バージョンを判定する場合は、チャネル名を除いた数値部分を比較します。
string rawVersion =
webView.CoreWebView2.Environment.BrowserVersionString;
string numericVersion = rawVersion.Split(' ')[0];
if (!Version.TryParse(numericVersion, out var actualVersion) ||
actualVersion.CompareTo(new Version(152, 0, 4181, 0)) < 0)
{
throw new InvalidOperationException(
$"WebView2 Runtime 152.0.4181.0以上が必要です。現在: {rawVersion}");
}
BrowserVersionStringには、使用中のWebView2環境のバージョンと、必要に応じてBeta、Dev、Canaryなどのチャネル名が含まれます。(Microsoft Learn)
本番アプリで起動自体を拒否するかどうかは、業務影響を考慮して決めてください。一般的には、次の情報をログへ記録したうえで、古いRuntimeの場合は更新を促す方法が扱いやすくなります。
- WebView2 SDKのバージョン
- 実際に選択されたRuntimeバージョン
- OSのバージョン
- .NETまたは.NET Frameworkのバージョン
- GPUとディスプレイドライバー
- 接続中のモニター数
- 例外コードとスタックトレース
安定版とPreview版のどちらを配布するか
Preview Runtimeは、本番向けの安定版Runtimeではありません。Microsoftは、Preview Runtimeを早期テストや社内でのセルフホスティングに利用し、Stable Evergreen Runtimeへ変更が入る前に問題を検出する用途として案内しています。(Microsoft Learn)
執筆時点では、NuGetにRelease版のMicrosoft.Web.WebView2 1.0.4191.47も公開されています。2026年8月28日に更新されたパッケージであり、Prereleaseではありません。(NuGet)
ただし、モニター変更時のクラッシュ修正を明示しているMicrosoft Learnの記録は、1.0.4181-prerelease側です。したがって、本番対応は次の順序が安全です。
1.0.4181-prereleaseとPreview Runtime152.0.4181.0以上で、問題が修正されることを再現環境で確認する- Release版
1.0.4191.47をステージング環境へ適用する - 同じモニター切断試験を実施する
- 修正を確認できたRelease版を本番配布する
- Release版で再現する場合のみ、Preview版の限定配布を検討する
パッケージ番号が新しいという理由だけで修正包含を断定せず、実際の再現手順で合否を判定することが重要です。
Runtimeの配布方式別に対応を決める
WebView2 Runtimeには、主にEvergreenとFixed Versionの2種類の配布方式があります。
| 配布方式 | 特徴 | 今回の対応 |
|---|---|---|
| Evergreen | 端末内の共有Runtimeを自動更新する | 更新済みRuntimeが端末へ届いたかログで確認する |
| Fixed Version | アプリへ特定バージョンを同梱する | 修正版Runtimeのフォルダーへ入れ替えて再配布する |
| Previewチャネル | Beta、Dev、Canaryを利用する | 検証や限定的な先行展開に使う |
Evergreen Runtimeを使用している場合
Evergreenでは、複数のアプリが共有するWebView2 Runtimeが自動更新されます。ディスク使用量や保守性の面から、Microsoftは多くのアプリにEvergreenを推奨しています。(Microsoft Learn)
一方で、アプリ側からすべての端末に対して特定のRuntimeバージョンを固定することはできません。そのため、次の対策を組み合わせます。
- 起動時に
BrowserVersionStringをログへ記録する - 古い端末だけを抽出する
- Evergreen BootstrapperまたはStandalone Installerを配布する
- アプリを完全終了してから再起動する
- 再起動後に実際のRuntimeバージョンを再確認する
Fixed Version Runtimeを使用している場合
Fixed Versionでは、アプリが使用するRuntimeを開発者が管理します。今回のように特定の修正を確実に配布したい場合は、Runtimeのバージョンを制御しやすい方式です。
ただし、古いRuntimeが自動更新されないため、修正版フォルダーへの入れ替えだけでなく、今後のセキュリティ更新も継続して配布する必要があります。(Microsoft Learn)
更新時は次を確認してください。
- 修正版Runtimeの全ファイルが配布物に含まれている
browserExecutableFolderが新しいRuntimeフォルダーを指している- 古いRuntimeフォルダーが誤って選択されない
- x86、x64、ARM64の対象アーキテクチャが正しい
- アプリ更新後に
BrowserVersionStringが想定どおりになっている
修正後に実施する回帰テスト
単にアプリが起動することを確認しただけでは不十分です。モニター構成変更の前後で、描画と操作が継続できることを確認します。
| テスト | 操作 | 合格条件 |
|---|---|---|
| 外部モニター切断 | 外部画面上にアプリを置いてケーブルを抜く | クラッシュせず、内蔵画面で再描画される |
| ドック切断 | USB-Cドックを取り外す | WebView2の表示と入力が継続する |
| 表示モード変更 | 拡張、複製、PC画面のみを切り替える | 描画停止や例外が発生しない |
| 再接続 | 切断したモニターを再接続する | WebView2が再描画され、操作できる |
| DPI変更 | 倍率の異なるモニターへ切り替える | ぼやけ、位置ずれ、クリックずれがない |
| 連続切り替え | 接続と切断を10~20回繰り返す | メモリ増加や断続的クラッシュがない |
| ナビゲーション | 構成変更後にページ遷移する | 正常に読み込みが完了する |
| 入力 | テキスト入力、スクロール、クリックを行う | 入力が欠落せず、フォーカスも正常 |
| 終了・再起動 | 構成変更後にアプリを終了して再起動する | WebView2プロセスが残留せず正常起動する |
特に重要なのは、アプリを表示しているモニター自体を切断するテストです。ウィンドウを別のモニターへドラッグするだけでは、公開された再現条件を十分に検証できません。
すぐに更新できない場合の暫定回避策
修正版をすぐ本番配布できない場合は、恒久対応までの暫定策を用意します。
モニター変更前にアプリを終了してもらう
業務アプリで利用者数が少ない場合は、最も安全な暫定策です。
「ドックを外す前にアプリを終了する」「外部モニターを取り外した後にアプリを再起動する」と案内します。操作性は下がりますが、壊れたWebView2コントロールをそのまま使い続けるより安全です。
WM_DISPLAYCHANGEを検出してコントロールを作り直す
公開された再現報告では、WM_DISPLAYCHANGEを検出し、WebView2CompositionControlを完全に破棄して作り直す回避策が使用されていました。(GitHub)
再作成時には、最低でも次の状態を復元する必要があります。
- 表示中のURL
- ナビゲーション状態
- イベントハンドラー
- Webメッセージ処理
- ホストオブジェクト
- 初期化スクリプト
- ユーザーデータフォルダー
- ズーム倍率
- アプリ側で保持している入力内容
注意点として、Dispose()したWebView2CompositionControlの同じインスタンスを再初期化することはできません。破棄後は、新しいコントロールインスタンスを生成する必要があります。(Microsoft Learn)
標準WebView2へ切り替える
Composition制御を使用する理由がなく、標準のWebView2でも画面要件を満たせる場合は、コントロールの変更を検討できます。
ただし、WebView2CompositionControlはWPF内の重なり表示など、標準WebView2とは異なる表示要件で採用されることがあります。切り替える場合は、ポップアップ、オーバーレイ、透過表示、入力、スクロールなどを一通り確認してください。
内部クラスをリフレクションで書き換えない
再現報告では、内部のGraphicsItemD3DImageに対するリフレクションを使った回避策も示されています。しかし、非公開実装への依存はWebView2 SDKの更新で簡単に壊れます。恒久対策として本番コードへ組み込む方法は推奨できません。
よくある対応ミス
| 対応ミス | 正しい判断 |
|---|---|
| SDKだけ更新する | 対応Runtimeと組み合わせて再ビルド・再検証する |
| Runtimeだけ更新する | 配布済みアプリ内のWebView2 DLLも確認する |
| 例外を握りつぶす | 修正版を適用し、描画が継続することを確認する |
| アプリが終了しなければ修正済みと判断する | WebView2の再描画、入力、ナビゲーションまで確認する |
| .NET 8なら絶対に発生しないと考える | 使用中のフレームワークごとに実機テストする |
| ウィンドウ移動だけをテストする | モニター切断や表示モード変更を実施する |
| インストール済み一覧だけを見る | BrowserVersionStringで実使用Runtimeを記録する |
| Preview版を全端末へ一斉配布する | 検証端末、先行利用者、本番の順に段階展開する |
WebView2 WPFのモニター変更クラッシュ対応まとめ
WebView2 WPFアプリがモニター構成変更時に落ちる場合は、まずWebView2CompositionControlまたはCoreWebView2CompositionControllerを使用しているか確認してください。
該当する場合は、次の順序で対応します。
- Microsoft.Web.WebView2 SDKの現在のバージョンを確認する
1.0.4181-prereleaseとPreview Runtime152.0.4181.0以上で修正を検証する- 実際に選択されたRuntimeを
BrowserVersionStringで記録する - モニター切断、ドック解除、表示モード変更をテストする
- Release版でも同じ試験を行う
- 検証済みのSDKとRuntimeを段階的に配布する
- 更新できない期間だけ、再起動やコントロール再作成を暫定策として使う
Microsoftはこの問題を修正済みとしているため、例外処理やGPUドライバー更新だけで回避し続けるのではなく、修正を含むWebView2 SDKとRuntimeへ移行することが本来の対応です。

コメント