解决 WebView2 中 HostObject 调用窗体关闭时的 InvalidCastException 与线程问题
在使用 Microsoft Edge WebView2 构建 WPF 桌面应用时,我们经常需要从网页 JavaScript 中调用 .NET 方法——例如点击网页按钮后关闭当前窗口。这通常通过 AddHostObjectToScript 注入一个 [ComVisible] 的 .NET 对象(称为 HostObject)来实现。
然而,许多开发者会遇到如下异常:
System.InvalidCastException: 无法将类型为'System.__ComObject'的 COM 对象强制转换为接口类型 'Microsoft.Web.WebView2.Core.Raw.ICoreWebView2Controller'。此操作失败的原因是对 IID 为'{4D00C0D1-9434-4EB6-8078-8697A560334F}'的接口的 COM 组件调用 QueryInterface 因以下错误而失败:不支持此接口 (异常来自 HRESULT:0x80004002 (E_NOINTERFACE))。
更棘手的是,即使绕过该异常,在 HostObject 中直接调用 Window.Close() 也可能导致线程访问异常或无响应。
本文将深入剖析这两个问题,并提供安全、可靠、符合最佳实践的完整解决方案。
一、问题根源分析
1. InvalidCastException:COM 接口不支持
该错误的核心是:
WebView2 SDK 版本 > 运行时(Runtime)版本
当你使用较新的 Microsoft.Web.WebView2 NuGet 包(如 v1.0.2700+),但目标机器上的 WebView2 Runtime(或 Edge 浏览器)版本较旧时,某些新定义的 COM 接口(如 ICoreWebView2Controller)在旧运行时中并不存在。此时尝试强制转换就会触发 E_NOINTERFACE 错误。
⚠️ 注意:不要手动引用 Microsoft.Web.WebView2.Core.Raw 命名空间中的接口,这些是内部实现,不应由应用代码直接使用。
2. HostObject 中关闭窗体失败:跨线程访问 UI
HostObject 的方法是从 WebView2 渲染线程(非 UI 线程) 调用的,而 WPF 的 Window 对象只能在创建它的 STA UI 线程 上访问。直接调用 window.Close() 会抛出:
System.InvalidOperationException: The calling thread cannot access this object...
二、解决方案
✅ 步骤 1:确保 WebView2 环境兼容
- 确保用户安装最新 WebView2 Runtime
- 引导用户访问 https://developer.microsoft.com/en-us/microsoft-edge/webview2/ 安装 Evergreen Bootstrapper。
- 或检查 Edge 浏览器是否为最新版(WebView2 随 Edge 自动更新)。

