簡單呼叫本機功能,例如列印,獲取硬體資訊,獲取本機使用者名稱,攔截JS功能,攔截錯誤資訊等等..
廢話不多說先來截圖
使用 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)
{
//使用 JsBridge
InitializeBridgeAsync(e.WebView);
}
#region JsBridge
static 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>
歡迎大佬加入Maui Blazor 中文社群QQ群 645660665 ,感謝star 相關開源專案
群專案快速入門
https://github.com/densen2014/BlazorHybrid/blob/master/快速上手.md?wt.mc_id=DT-MVP-5005078