废话不多说先来截图
使用 JsBridge
JsBridge不科普了,同学们自行百度一下
BlazorWebView.cs
using Microsoft.AspNetCore.Components.WebView;
using Microsoft.AspNetCore.Components.WebView.WindowsForms;
using Microsoft.VisualBasic.ApplicationServices;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
using System.Runtime.InteropServices;
using WebView2Control = Microsoft.Web.WebView2.WinForms.WebView2;public partial class InitBlazorWebView
{BlazorWebView _blazorWebView;public InitBlazorWebView(BlazorWebView blazorWebView){_blazorWebView = blazorWebView;_blazorWebView.BlazorWebViewInitialized += BlazorWebViewInitialized;}void BlazorWebViewInitialized(object sender, BlazorWebViewInitializedEventArgs e){//使用 JsBridgeInitializeBridgeAsync(e.WebView);}#region JsBridgestatic BridgeObject obj = new BridgeObject();/// <summary>/// 自定义宿主类,用于向网页注册C#对象,供JS调用/// </summary>[ClassInterface(ClassInterfaceType.AutoDual)][ComVisible(true)]public class Bridge{public string Func(string param) => $"Func返回 {param} {obj.MacAdress}";public string Print(object param) => $"Print返回 {param}";public void PrintDemo(object param) => MessageBox.Show($"Print {param}");public void Alert(string param) => MessageBox.Show(param);public string GetUserName() => Environment.MachineName + "/" + Environment.UserDomainName + "/" + System.Windows.Forms.SystemInformation.UserName ;}public class BridgeObject{public string MacAdress => $"{DateTime.Now:G}";}async void InitializeBridgeAsync(WebView2Control webView){webView.CoreWebView2.AddHostObjectToScript("bridge", new Bridge());await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("var bridge= window.chrome.webview.hostObjects.bridge;");await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync($"localStorage.setItem('macAdress', '{obj.MacAdress}')");}#endregion
}
Blazor测试组件
Tips: 不一定要在win端执行,在远端部署也可以的.
JsBridge.razor
@using BootstrapBlazor.Components<GroupBox Title="Bridge"><Button Text="GetMacAdress" OnClick="GetMacAdress" IsDisabled="!BridgeEnabled" /><Button Text="Print" OnClick="OnPrint" IsDisabled="!BridgeEnabled" /><Button Text="用户名" OnClick="GetUserName" IsDisabled="!BridgeEnabled" />
</GroupBox><GroupBox Title="拦截JS"><button class="btn btn-primary" role="button" onclick="alert('来自Blazor的alert警告框')">Alert</button><button class="btn btn-primary" role="button" onclick="console.error('You made a mistake')">console.error</button><button class="btn btn-primary" role="button" onclick="print('来自Blazor的print')">Print</button>
</GroupBox>
<pre>
@message
</pre>
JsBridge.razor.cs
public partial class JsBridge
{string? message;bool BridgeEnabled;[Inject, NotNull]IJSRuntime? JS { get; set; }[Inject, NotNull]ToastService? ToastService { get; set; }[Inject, NotNull]IJSRuntime? JS { get; set; }[Inject, NotNull]ToastService? ToastService { get; set; }//private IJSObjectReference? module;async Task GetMacAdress(){//message = await module!.InvokeAsync<string>("GetMacAdress");//await ToastService.Information("JS方式 macAdress", message);message = await JS!.InvokeAsync<string>("eval", $"localStorage.getItem('macAdress');");await ToastService.Information("eval macAdress", message);message = await JS!.InvokeAsync<string>("eval", "bridge.Func('测试')");await ToastService.Information("eval bridge.Func", message);}async Task OnPrint(){message = await JS!.InvokeAsync<string>("eval", $"bridge.Print('打印文本123456789')");await ToastService.Information("eval bridge.Print", message);message = await JS!.InvokeAsync<string>("eval", $"bridge.Print({ItemsPrint.ObjectToJson()})");await ToastService.Information("eval bridge.Print object", message);}async Task GetUserName(){message = await JS!.InvokeAsync<string>("eval", $"bridge.GetUserName()");await ToastService.Information("eval bridge.GetUserName", message);}string[] ItemsPrint = ["Item1", "Item2", "Item3"];protected override async Task OnAfterRenderAsync(bool firstRender){try{if (firstRender){BridgeEnabled = await JS!.InvokeAsync<bool>("eval", $"typeof bridge != 'undefined'");message = await JS!.InvokeAsync<string>("eval", $"localStorage.getItem('macAdress');");}}catch (Exception e){message = e.Message;}StateHasChanged();}}
win端js拦截方式
BlazorHybrid.Win/wwwroot/jsbridge.js
function alert(message) {console.info(message);if (bridge != null) {//调用C#方法bridge.Alert(message);}
} var oldPrintFunction = window.print;
var oldConsoleErrorFunction = console.error;window.print = function (e) {console.log('Gonna do some special stuff');if (bridge != null) {//调用C#方法bridge.PrintDemo('打印对象示例: '+e);} else {oldPrintFunction();}
};
console.error = function (e) {if (bridge != null) {//调用C#方法bridge.Alert(e);} else {oldConsoleErrorFunction(e);}
};function beforePrint() {console.log('Do something special before print');
}function afterPrint() {console.log('Do something after print');
}if (window.matchMedia) {window.matchMedia('print').addListener(function (mql) {if (mql.matches) {beforePrint();}else {afterPrint();}});
}// For IE, does not attach in browsers that do not support these events
window.addEventListener('beforeprint', beforePrint, false);
window.addEventListener('afterprint', afterPrint, false);
BlazorHybrid.Win/wwwroot/index.html
<script src="jsbridge.js"></script>