Как исправить ошибку E_UNEXPECTED (8000FFFF) в WebView2
Ошибка E_UNEXPECTED (8000FFFF) появляется, если WebView2 вызывается до инициализации CoreWebView2. Нужно дождаться инициализации или событие, задать Source.
Как исправить ошибку E_UNEXPECTED (8000FFFF) при работе с элементом WebView2 в приложении ReactiveUI Windows?
Я создаю WebView2 в XAML и передаю контрол в менеджер, который устанавливает URI. Метод Initialize выглядит так:
class WebViewManager
{
private readonly WebView2 webView2Element;
public Task<Result<Unit>> Initialize(WebView2 webView2Element, CancellationToken cancellationToken = default)
{
this.WebView2Element = webView2Element.ThrowIfNull();
_ = this.WebView2Element.EnsureCoreWebView2Async();
}
}
Initialize вызывается из WhenActivated в коде за окном, так что он выполняется на UI‑потоке. Я проверил, что WebView2 runtime установлен на машине.
Тем не менее, любой доступ к свойству Source или вызов других методов на WebView2 приводит к исключению E_UNEXPECTED (8000FFFF) из Microsoft.Web.WebView2.Core.dll. Я даже пробовал ставить вызовы в диспетчер, но без результата.
Что именно вызывает это исключение и как правильно инициализировать и использовать WebView2 в таком случае?
The E_UNEXPECTED (0x8000FFFF) you see is not a bug in your code—it’s a symptom of calling WebView2 APIs before the control’s CoreWebView2 object is fully initialized.
Because EnsureCoreWebView2Async() is an async method, you must wait for it to finish (or handle its completion event) before touching any other properties or methods.
Содержание
- Почему возникает ошибка
- Правильный способ инициализации
- ReactiveUI‑специфичные рекомендации
- Что делать, если всё равно падает
- Заключение
Почему возникает ошибка
EnsureCoreWebView2Async() kicks off an asynchronous initialization sequence inside the WebView2 runtime.
If you call Source, Navigate, or any other member before this sequence completes, the underlying COM object is in an uninitialized state and throws E_UNEXPECTED.
This pattern is confirmed in several community reports:
- In the GitHub issue “
COMException8000FFFF duringEnsureCoreWebView2Async” the culprit was a missing await, leading to an uninitialized CoreWebView2 【GitHub 2401】. - The StackOverflow question “E_UNEXPECTED (8000FFFF) error while calling functions on a WebView2 element” mirrors the same symptom: accessing properties too early after
EnsureCoreWebView2Async()【StackOverflow 79837309】. - The “EnsureCoreWebView2Async not ready even after CoreWebView2InitializationCompleted” issue shows that the
CoreWebView2InitializationCompletedevent can fire, yet the control still throws if you try to use it before awaiting the async call 【StackOverflow 66550671】.
Правильный способ инициализации
-
Await the async call (or subscribe to the completion event).
csharppublic async Task<Result<Unit>> InitializeAsync(WebView2 webView2, CancellationToken ct = default) { this.WebView2Element = webView2.ThrowIfNull(); // Wait for initialization to finish await this.WebView2Element.EnsureCoreWebView2Async(); // Now safe to use this.WebView2Element.Source = new Uri("https://example.com"); return Result.Ok(); } -
Prefer the event if you need to react immediately after initialization:
csharpthis.WebView2Element.CoreWebView2InitializationCompleted += (_, _) => { // Initialization succeeded – safe to use this.WebView2Element.Source = new Uri("https://example.com"); }; -
Avoid “fire‑and‑forget” patterns such as
_ = this.WebView2Element.EnsureCoreWebView2Async();.
The compiler will warn you if you discard aTaskthat can fault. -
Make sure the control is loaded (
Loadedevent orWhenActivatedafter the view is rendered).
If you callEnsureCoreWebView2Asyncbefore the element’s native window handle exists, initialization will fail.
ReactiveUI‑специфичные рекомендации
- In
WhenActivated, wrap the async call insideObservable.StartAsyncor useInvokeAsyncto keep the UI thread context:csharpthis.WhenActivated(disposables => { Observable .StartAsync(async () => await _manager.InitializeAsync(_webView2)) .Subscribe() .DisposeWith(disposables); }); - Do not assign the
Sourceproperty in the constructor or beforeWhenActivated; do it after theawaitcompletes.
Что делать, если всё равно падает
| Symptom | Likely cause | Fix |
|---|---|---|
EnsureCoreWebView2Async throws COMException 0x8000FFFF |
WebView2 runtime not found or corrupted | Re‑install the WebView2 Runtime (Microsoft Edge WebView2 Runtime) or update the NuGet package. |
| Initialization completes but later calls still throw | Multiple WebView2 controls sharing the same environment without proper disposal | Use a separate CoreWebView2Environment per control or dispose the previous controller. |
| Error appears only on some machines | DPI awareness or OS configuration (see GitHub issue 2234) | Set ProcessDpiAwareness to PerMonitorAwareV2 or update to the latest runtime. |
Заключение
The E_UNEXPECTED error is a direct consequence of trying to touch WebView2 before its CoreWebView2 object is fully ready.
By awaiting EnsureCoreWebView2Async() or handling the CoreWebView2InitializationCompleted event, and by ensuring the control is loaded on the UI thread, you can reliably set the Source and call other methods.
If problems persist, verify that the WebView2 runtime is correctly installed and that you’re not inadvertently creating multiple controls without proper disposal.
Источники
- COMException 8000FFFF during EnsureCoreWebView2Async – GitHub Issue #2401
- E_UNEXPECTED (8000FFFF) error while calling functions on a WebView2 element – StackOverflow
- EnsureCoreWebView2Async not ready even after CoreWebView2InitializationCompleted – StackOverflow
- WebView2 EnsureCoreWebView2Async always throws exception – GitHub Issue #1778
- CreateCoreWebView2Controller returns 0x8000ffff (E_UNEXPECTED) when DPI set to Unaware – GitHub Issue #2234