You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP中WebView2的AddHostObjectToScript是否必须依赖C++ WinRT适配器?

UWP WebView2 JS与C#交互:无需WinRT C++适配器的实现方案

是否必须依赖WinRT C++适配器?

不需要。你之前遇到的报错,本质是普通C#类未满足WebView2在UWP环境下的跨语言交互要求,而非必须依赖第三方适配器。WebView2本身提供了原生的交互机制,只要遵循WinRT兼容规则即可实现JS直接调用C#代码。

方案1:使用标记[AllowForWeb]的WinRT组件

这是最直接的原生方案,利用WinRT的跨语言交互能力:

  1. 创建WinRT组件类
    新建一个WinRT组件项目(或在现有UWP项目中添加符合WinRT规范的类),给类和需要暴露的方法添加[AllowForWeb]属性,同时确保参数/返回值使用WinRT兼容类型(如string、int、IAsyncOperation<T>等,避免使用普通Task<T>):

    using Windows.Foundation;
    using Windows.Foundation.Metadata;
    
    [AllowForWeb]
    public sealed class MessageCallWrapper
    {
        // 同步方法
        public string SyncMessage(string input)
        {
            return $"C# received: {input}";
        }
    
        // 异步方法(必须返回IAsyncOperation<T>)
        public IAsyncOperation<string> AsyncMessage(string input)
        {
            return AsyncInfo.Run(async token =>
            {
                await Task.Delay(1000);
                return $"C# async received: {input}";
            });
        }
    }
    
  2. 在UWP项目中绑定到WebView2
    确保CoreWebView2初始化完成后,直接将实例添加为宿主对象:

    // 等待CoreWebView2初始化
    await WebViewContainer.EnsureCoreWebView2Async();
    var wrapper = new MessageCallWrapper();
    WebViewContainer.CoreWebView2.AddHostObjectToScript("external", wrapper);
    
  3. JS端调用
    直接通过全局对象调用C#方法:

    // 同步调用
    const syncResult = window.external.SyncMessage("Hello JS");
    console.log(syncResult);
    
    // 异步调用
    window.external.AsyncMessage("Hello Async JS")
        .then(asyncResult => console.log(asyncResult));
    

方案2:基于消息传递的轻量交互

如果不需要直接暴露C#对象,可通过WebView2原生的消息机制实现双向交互:

  1. C#端监听消息并响应
    订阅CoreWebView2.WebMessageReceived事件,处理JS发送的消息,再通过ExecuteScriptAsync返回结果:

    // 初始化后绑定事件
    WebViewContainer.CoreWebView2.WebMessageReceived += (sender, args) =>
    {
        string jsMessage = args.WebMessageAsJson;
        // 解析消息(比如JSON格式)
        string response = $"Processed message: {jsMessage}";
        // 执行JS代码返回响应
        _ = WebViewContainer.CoreWebView2.ExecuteScriptAsync($"handleResponse('{response}')");
    };
    
  2. JS端发送消息并接收响应
    使用window.chrome.webview.postMessage发送消息,定义回调函数接收C#返回的结果:

    // 发送消息到C#
    window.chrome.webview.postMessage(JSON.stringify({type: "greet", content: "Hello from JS"}));
    
    // 接收C#响应
    function handleResponse(response) {
        console.log("Received from C#:", response);
    }
    

为什么之前不用适配器会报错?

常见原因包括:

  • 普通C#类未标记[AllowForWeb],WinRT运行时无法识别为可跨语言访问的类型;
  • 使用了WinRT不支持的类型(如Task<T>而非IAsyncOperation<T>);
  • 类未声明为sealed(WinRT组件类必须是密封类)。

内容的提问来源于stack exchange,提问作者user2566892

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 23:05:00