BlazorHybrid 通过Blazor简单调用本机功能

简单调用本机功能,例如打印,获取硬件信息,获取本机用户名,拦截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" οnclick="alert('来自Blazor的alert警告框')">Alert</button>
    <button class="btn btn-primary" role="button" οnclick="console.error('You made a mistake')">console.error</button>

    <button class="btn btn-primary" role="button" οnclick="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/%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B.md?wt.mc_id=DT-MVP-5005078

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Densen2014

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值