You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用C#和Microsoft WebView2控件从异步JavaScript脚本获取结果?

如何使用C#和Microsoft WebView2控件从异步JavaScript脚本获取结果?

嘿,我来给你一步步拆解怎么用C#搭配WebView2控件,从异步JavaScript脚本里拿到想要的结果!其实核心就是利用WebView2的脚本执行能力,配合C#的异步编程来处理JS的异步返回值,下面我给你详细说。

1. 先把WebView2控件的初始化搞定

首先你得给项目装上WebView2的NuGet包(Microsoft.Web.WebView2),然后在代码里确保WebView2已经完成初始化——毕竟控件没准备好,啥脚本也执行不了。你可以用EnsureCoreWebView2Async方法等着它初始化完成,或者监听CoreWebView2InitializationCompleted事件,等触发了再干活。

给你整个示例代码:

using Microsoft.Web.WebView2.WinForms;
// 假设你在WinForms里有个WebView2控件实例叫webView21
async void SetupWebView()
{
    // 等待控件初始化完成
    await webView21.EnsureCoreWebView2Async();
    // 初始化完了再搞脚本相关的操作
}

2. 把你的异步JS脚本写到位

就像你提供的那个获取IP的异步函数,咱们把它理清楚,确保它能正确返回Promise结果(毕竟async函数本身就返回Promise):

async function getIPAddress() {
    var thisFuncName = arguments.callee.toString().match(/function ([^\(]+)/)[1];
    var retValue = {
        'Result': true,
        'ResultText': '',
        'Message': '',
        'ScriptFuncName': thisFuncName
    };

    try {
        const response = await fetch('https://api.ipify.org?format=json');
        if (response.ok) {
            const data = await response.json();
            retValue.ResultText = data.ip;
            retValue.Message = "IP获取成功";
        } else {
            retValue.Result = false;
            retValue.Message = "请求失败,状态码:" + response.status;
        }
    } catch (error) {
        retValue.Result = false;
        retValue.Message = "发生错误:" + error.message;
    }
    return retValue;
}

3. 在C#里调用异步JS并拿结果

WebView2的CoreWebView2.ExecuteScriptAsync方法是关键,它能执行JS代码,而且返回的是Task<string>——刚好能配合C#的异步await来处理JS的异步结果。咱们要做的就是让JS返回异步函数的最终值,然后在C#里解析这个结果。

首先,先定义一个和JS返回结构对应的C#类,这样解析JSON会方便很多:

// 这个类的字段要和JS里的retValue结构对应上
public class JsExecutionResult
{
    public bool Result { get; set; }
    public string ResultText { get; set; }
    public string Message { get; set; }
    public string ScriptFuncName { get; set; }
}

然后写调用脚本并解析结果的方法:

async Task<JsExecutionResult> FetchIpFromJavaScript()
{
    // 先检查控件有没有初始化,没的话先等它初始化完
    if (webView21.CoreWebView2 == null)
    {
        await webView21.EnsureCoreWebView2Async();
    }

    // 执行异步JS函数,这里必须加await,不然拿到的是Promise对象不是最终结果
    string jsCommand = "await getIPAddress();";
    string jsonResponse = await webView21.CoreWebView2.ExecuteScriptAsync(jsCommand);

    // 把JSON字符串转成C#对象,这里用System.Text.Json,你也可以用Newtonsoft.Json
    using var jsonDocument = JsonDocument.Parse(jsonResponse);
    var result = jsonDocument.RootElement.Deserialize<JsExecutionResult>();
    return result;
}

4. 用上拿到的结果

最后你就可以在按钮点击或者其他事件里调用这个方法,处理返回的结果啦:

async void GetIpButton_Click(object sender, EventArgs e)
{
    var ipResult = await FetchIpFromJavaScript();
    if (ipResult.Result)
    {
        MessageBox.Show($"搞定啦!IP是:{ipResult.ResultText}\n来自函数:{ipResult.ScriptFuncName}");
    }
    else
    {
        MessageBox.Show("哎呀出错了:" + ipResult.Message);
    }
}

几个要注意的点

  • 千万要等WebView2初始化完成再执行脚本,不然直接报错给你看!
  • ExecuteScriptAsync返回的是JSON格式的字符串,所以一定要用JSON库转成C#实体类,不然一堆字符串处理起来太麻烦。
  • 调用异步JS函数时,JS代码里必须加await,不然你拿到的是Promise对象,不是你要的最终结果,这一步很容易忘!

备注:内容来源于stack exchange,提问作者ShamilS

火山引擎 最新活动