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

news2025/2/24 10:07:34

简单调用本机功能,例如打印,获取硬件信息,获取本机用户名,拦截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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1902234.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

easyx图形库

目录 1、绘制简单的图形化窗口 2、设置窗口属性 2.1 颜色设置 2.2 刷新 3、基本绘图函数 3.1 绘制直线 3.2 绘制圆 3.3 绘制矩形 4、贴图 4.1 原样贴图 4.1.1 IMAGE变量去表示图片 4.1.2 加载图片 4.1.3 显示图片 4.2 透明贴图 4.2.1 认识素材 4.3 png贴图 5…

辣子简报芬芳喜事特辑

【辣子简报芬芳喜事特辑】&#x1f389;在这个季节的尾声&#xff0c;当一缕阳光温柔地洒在打包好的行囊上&#xff0c;我们不约而同地停下了忙碌的脚步&#xff0c;回望那段共同编织的璀璨时光——79天的并肩作战&#xff0c;如同一段精彩绝伦的旅程&#xff0c;如今已缓缓驶向…

taoCMS v3.0.2 任意文件读取漏洞(CVE-2022-23316)

前言 CVE-2022-23316 是一个影响 taoCMS v3.0.2 的漏洞。这个漏洞允许攻击者通过 admin.php?actionfile&ctrldownload&path../../1.txt 的路径读取任意文件。攻击者可以利用该漏洞读取服务器上的任何文件&#xff0c;只要他们知道文件的路径​ (OpenCVE)​​ (Tenabl…

Java多语言跨境电商外贸商城源码 tiktok商城系统源码 跨境电商源码

Java多语言跨境电商外贸商城源码 tiktok商城系统源码 跨境电商源码 技术栈 PC端使用&#xff1a;vueelementui 用户端使用&#xff1a;uniapp 管理端使用&#xff1a;vueelementui 后台服务使用&#xff1a;springbootmybatisplusmysql 功能描述&#xff1a; 对接PayPal…

IDEA配Git

目录 前言 1.创建Git仓库&#xff0c;获得可提交渠道 2.选择本地提交的项目名 3.配置远程仓库的地址 4.新增远程仓库地址 5.开始进行commit操作 6.push由于邮箱问题被拒绝的解决方法&#xff1a; 后记 前言 以下操作都是基于你已经下载了Git的前提下进行的&#xff0c…

源码航行阅读目录

&#x1f3c0; 前言 在准备面试和学习的过程中&#xff0c;我阅读了比较多的源码&#xff0c;比如 JUC、Spring、MyBatis&#xff0c;收获了很多代码的设计思想&#xff0c;也对平时调用的 API 有了更深入的理解&#xff1b;但过多散乱的笔记给我的整理复习带来了比较大的麻烦…

前端vue后端java使用easyexcel框架下载表格xls数据工具类

一 使用alibaba开源的 easyexcel框架&#xff0c;后台只需一个工具类即可实现下载 后端下载实现 依赖 pom.xml <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependen…

第三方商城对接重构(HF202407)

文章目录 项目背景一、模块范围二、问题方案1. 商品模块整体来说这块对接的不是太顺利,梳理了几条大概的思路:2. 订单模块3. 售后4. 发票5. 结算单经验总结项目背景 作为供应商入围第三方商城成功,然后运营了一段时间,第三方通知要重构, 需要重新对接打通接口完成系统对接…

树型结构数据存储实践

很多业务场景会遇到树形结构的数据&#xff0c;如公司的人员职级树、行政区划树等。 使用类似MySQL的数据库进行存储&#xff0c;需要将树形结构&#xff08;二维&#xff09;存储到行格式&#xff08;一维&#xff09;的db中。 本文介绍了树型结构数据存储的三种方式&#xf…

ShardingSphere实战

ShardingSphere实战 文章目录 ShardingSphere实战分库分表实战建表建表sql利用存储过程建表Sharding-jdbc分库分表配置 基于业务的Sharding-key考虑订单id用户id分片策略订单id的设计与实现**设计思想**&#xff1a;设计思路&#xff1a; 具体分片策略实现测试数据插入商户商品…

计算机提示由于找不到concrt140.dll怎么办,7种解决方法可以对比

在电脑中打开游戏或许软件出现找不到concrt140.dll无法继续执行代码怎么办&#xff1f;concrt140.dll是什么&#xff1f;丢失要怎么解决&#xff1f;下面给大家分析一下concrt140.dll文件是什么与concrt140.dll丢失的多种解决方法&#xff01;相信对你有帮助&#xff01; 一、c…

SpringSecurity6.x使用教程

SpringSecurity6.x使用 SpringSecurity版本 SpringSecurity目前支持的版本如下图所示&#xff0c;可以看到5.x的版本过几年就不会再维护了&#xff0c;6.x将成为主流。 入门 引入依赖 <dependency><groupId>org.springframework.boot</groupId><arti…

法国工程师IMT联盟 密码学及其应用 2022年期末考试

1 密码学 1.1 问题1 对称加密&#xff08;密钥加密) 1.1.1 问题 对称密钥la cryptographie symtrique和公开密钥有哪些优缺点&#xff1f; 1.1.1.1 对称加密&#xff08;密钥加密)的优缺点 1.1.1.1.1 优点 加解密速度快encrypt and decrypt&#xff1a;对称加密算法通常基于…

智能家居安防系统教学解决方案

前言 随着科技的不断进步和智能家居概念的深入人心&#xff0c;智能家居安防系统作为智能家居领域的重要组成部分&#xff0c;其重要性日益凸显。智能家居安防系统不仅能够提供环境和人员的监测功能&#xff0c;还能够采取措施降低或避免人员伤亡及财产损失。因此&#xff0c;…

XXL-JOB中断信号感知

目录 背景 思路 实现逻辑 总结 背景 在使用xxl-job框架时&#xff0c;由于系统是由线程池去做异步逻辑&#xff0c;然后主线程等待&#xff0c;在控制台手动停止时&#xff0c;会出现异步线程不感知信号中断的场景&#xff0c;如下场景 而此时如果人工在控制台停止xxl-job执…

超越YOLO! RT-DETR 实时目标检测技术介绍

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

Thisjavabean对象数组

This 1.概念 this是一个对象this是一个构造函数 2.介绍 解决局部变量和成员变量命名冲突 this在面向对象-封装那一篇里&#xff0c;有被两个地方提及。 但我们先简单给一个例子&#xff1a; public Person(String name, String phone, String qqPassword, String bankCar…

【踩坑】修复报错Cannot find DGL libdgl_sparse_pytorch_2.2.0.so

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 错误复现 原因分析 解决方法 错误复现 import dgldataset dgl.data.CoraGraphDataset() graph dataset[0] graph.adjacency_matrix() 原因分…

Python 学习中什么是元组,如何使用元组?

什么是元组 元组&#xff08;Tuple&#xff09;是Python内置的一种数据结构&#xff0c;用于存储多个数据项。与列表类似&#xff0c;元组也可以存储不同类型的数据&#xff0c;但它们之间存在一个重要区别&#xff1a;元组是不可变的&#xff0c;也就是说&#xff0c;一旦创建…

笔记13:switch多分支选择语句

引例&#xff1a; 输入1-5中的任意一共数字&#xff0c;对应的打印字符A,B,C,D,E int num 0; printf("Input a number[1,5]:"); scanf("%d"&#xff0c;&num); if( num 1)printf("A\n"); else if(num2)printf("B\n"); else i…