基于.Net CEF 实现 Vue 等前端技术栈构建 Windows 窗体应用

零、参考资料

1、https://github.com/cefsharp/CefSharp/wiki/Quick-Start-For-MS-.Net-5.0-or-greater

2、https://github.com/cefsharp/CefSharp/wiki/Quick-Start

3、https://github.com/cefsharp/CefSharp/wiki/General-Usage#javascript-integration

一、安装 Nuget 包

https://www.nuget.org/packages/CefSharp.WinForms

安装 CefSharp.WinForms 包后会显示 Readme.txt,

二、配置项目

<!-- CefWindowsFormsApp.csproj -->
<PropertyGroup Condition="'$(PlatformTarget)' == 'x64'"><RuntimeIdentifier Condition="'$(RuntimeIdentifier)' == ''">win-x64</RuntimeIdentifier><SelfContained Condition="'$(SelfContained)' == ''">false</SelfContained>
</PropertyGroup>

三、加载远程网页示例

使用 ChromiumWebBrowser 加载百度首页,

// Form1.cs
using CefSharp;
using CefSharp.WinForms;
using System.Windows.Forms;namespace CefWindowsFormsApp
{public partial class Form1 : Form{private static ChromiumWebBrowser browser;public Form1(){InitializeComponent();AddChromiumWebBrowser();}/// <summary>/// Create a new instance in code or add via the designer/// </summary>private void AddChromiumWebBrowser(){browser = new ChromiumWebBrowser("www.baidu.com");this.Controls.Add(browser);}private void Form1_Load(object sender, System.EventArgs e){// Load a urlbrowser.LoadUrl("https://www.baidu.com/");}}
}

这这个示例中,我们引入了 CefSharp 库,在 Form1 窗体中添加了浏览器控件 ChromiumWebBrowser ,并且在窗体启动时加载百度首页,

四、加载本地网页示例

首先创建一个 Vue 项目,

# 使用 Vite
cnpm create vite@latest# cd vite-project
# cnpm i

接着完成前端的开发之后,打包静态资源,

npm run build

然后在 WinForm 项目下创建 Resources 文件夹,把前端打包的 dist 文件夹下的文件全部复制过来,并且文件属性设置为“嵌入的资源”,

最后通过 RegisterScheme 注册为本地资源访问,

// Form1.cs
using CefSharp;
using CefSharp.SchemeHandler;
using CefSharp.WinForms;
using System.Windows.Forms;namespace CefWindowsFormsApp
{public partial class Form1 : Form{private static ChromiumWebBrowser browser;public Form1(){InitializeComponent();AddChromiumWebBrowser();}/// <summary>/// Create a new instance in code or add via the designer/// </summary>private void AddChromiumWebBrowser(){InitBrowser();browser = new ChromiumWebBrowser("http://cefsharp.test");this.Controls.Add(browser);}public static void InitBrowser(){// Pseudo code; you probably need more in your CefSettings also.var settings = new CefSettings();settings.RegisterScheme(new CefCustomScheme{SchemeName = "http",DomainName = "cefsharp.test",SchemeHandlerFactory = new FolderSchemeHandlerFactory(rootFolder: @"..\..\..\..\CefWindowsFormsApp\Resources",hostName: "cefsharp.test", //Optional param no hostname/domain checking if nulldefaultPage: "index.html") //Optional param will default to index.html});Cef.Initialize(settings);}private void Form1_Load(object sender, System.EventArgs e){// Load local urlbrowser.LoadUrl("http://cefsharp.test");}       }
}

效果如下,

五、调用 JS 代码

1、JS 无返回值

窗体页面调整,新增一个 Button 、一个 Pane,

注意,JavaScript 只能在 V8Context 中执行,这里的示例通过实现 IRenderProcessMessageHandler 接口、绑定 LoadingStateChanged 、FrameLoadEnd 两个事件来实现 DOM 加载时弹窗、页面资源加载完毕弹窗、主页面加载完毕弹窗,通过 “DoAlert” 按钮绑定事件来实现手动弹窗,

// Form1.cs
using CefSharp;
using CefSharp.SchemeHandler;
using CefSharp.WinForms;
using System.Windows.Forms;namespace CefWindowsFormsApp
{public partial class Form1 : Form{private static ChromiumWebBrowser browser;public Form1(){InitializeComponent();AddChromiumWebBrowser();}/// <summary>/// Create a new instance in code or add via the designer/// </summary>private void AddChromiumWebBrowser(){InitBrowser();browser = new ChromiumWebBrowser("http://cefsharp.test");browser.RenderProcessMessageHandler = new RenderProcessMessageHandler();// Wait for the page to finish loading (all resources will have been loaded, rendering is likely still happening)browser.LoadingStateChanged += (sender, args) =>{// Wait for the Page to finish loadingif (args.IsLoading == false){browser.ExecuteScriptAsync("alert('All Resources Have Loaded');");}};// Wait for the MainFrame to finish loadingbrowser.FrameLoadEnd += (sender, args) =>{// Wait for the MainFrame to finish loadingif (args.Frame.IsMain){args.Frame.ExecuteJavaScriptAsync("alert('MainFrame finished loading');");}};BrowserPanel.Controls.Add(browser);}public static void InitBrowser(){// Pseudo code; you probably need more in your CefSettings also.var settings = new CefSettings();settings.RegisterScheme(new CefCustomScheme{SchemeName = "http",DomainName = "cefsharp.test",SchemeHandlerFactory = new FolderSchemeHandlerFactory(rootFolder: @"..\..\..\..\CefWindowsFormsApp\Resources",hostName: "cefsharp.test", // Optional param no hostname/domain checking if nulldefaultPage: "index.html") // Optional param will default to index.html});Cef.Initialize(settings);}private void Form1_Load(object sender, System.EventArgs e){// Load a urlbrowser.LoadUrl("http://cefsharp.test");}public class RenderProcessMessageHandler : IRenderProcessMessageHandler{public void OnContextReleased(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame){throw new System.NotImplementedException();}public void OnFocusedNodeChanged(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IDomNode node){throw new System.NotImplementedException();}public void OnUncaughtException(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, JavascriptException exception){throw new System.NotImplementedException();}// Wait for the underlying JavaScript Context to be created. This is only called for the main frame.// If the page has no JavaScript, no context will be created.void IRenderProcessMessageHandler.OnContextCreated(IWebBrowser browserControl, IBrowser browser, IFrame frame){const string script = "document.addEventListener('DOMContentLoaded', function(){ alert('DomLoaded'); });";frame.ExecuteJavaScriptAsync(script);}}private void DoAlertBtn_Click(object sender, System.EventArgs e){browser.ExecuteScriptAsync("alert('Hello World!');");}}
}

效果如下,

2、JS 有返回值

        private async void DoAlertBtn_ClickAsync(object sender, System.EventArgs e){var script = @"(function() { let val = 1 + 1; return val; })();";JavascriptResponse response = await browser.GetBrowser().MainFrame.EvaluateScriptAsync(script);browser.ExecuteScriptAsync(string.Format("alert(' 1 + 1 = {0}');", (int)response.Result));}

六、Browser 调试器

browser.ShowDevTools();

七、app.manifest 清单文件

该清单文件是为了兼容 Win7、8、10 等系统差异,

<!-- example.exe.manifest -->
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"><assemblyIdentitytype="win32"name="Contoso.ExampleApplication.ExampleBinary"version="1.2.3.4"processorArchitecture="x86"/><description>Contoso Example Application</description><compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application><!-- Windows 10/11 --><supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> <!-- * ADD THIS LINE * --></application></compatibility>
</assembly>

八、发布

项目右键,选择 Release x64 模式“重新生成”,在 bin 目录下生成文件,

需要把该目录的所有文件复制到另一台相同 .Net 版本的电脑才能运行。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis篇---第五篇

系列文章目录 文章目录 系列文章目录一、MyBatis 中见过什么设计模式&#xff1f;二、MyBatis 中比如 UserMapper.java 是接口&#xff0c;为什么没有实现类还能调用&#xff1f; 一、MyBatis 中见过什么设计模式&#xff1f; 二、MyBatis 中比如 UserMapper.java 是接口&#…

【JavaEE】网络编程---UDP数据报套接字编程

一、UDP数据报套接字编程 1.1 DatagramSocket API DatagramSocket 是UDP Socket&#xff0c;用于发送和接收UDP数据报。 DatagramSocket 构造方法&#xff1a; DatagramSocket 方法&#xff1a; 1.2 DatagramPacket API DatagramPacket是UDP Socket发送和接收的数据报。…

vue el-dialog弹出框自定义指令实现拖拽改变位置-宽度-高度

前言 在实际开发中我们经常使用el-dialog弹出框做表单&#xff0c;一般情况都是居中。遮挡到了一部分数据 当我们想要查看弹出框下面的数据时&#xff0c;就只能先把弹出框关闭&#xff0c;查看完数据之后在打开弹框 我们通过动态样式&#xff0c;和鼠标事件就可以实现。但自…

最详细STM32,cubeMX 超声波测距

这篇文章将详细介绍 STM32使用 cubeMX驱动超声波测距 。 文章目录 前言一、超声波模块测距原理 &#xff1a; 二、cubeMX 配置三、实验程序总结 前言 实验材料&#xff1a;STM32F103C8T6开发板&#xff0c; HC-SR04 超声波模块。所需软件&#xff1a;keil5 &#xff0c; cubeM…

Ubuntu22.04系统 Cgroup v2 切换成v1

使用v1导致docker容器启动失败 Failed to mount cgroup at /sys/fs/cgroup/systemd: Operation not permitted Issue #4072 lxc/lxc GitHub https://github.com/lxc/lxc/issues/4072 原因&#xff1a;ubuntu自21.04版本后的版本&#xff08;不包含21.04&#xff09;linux内…

nginx创建站点“nginx: [emerg] host not found in upstream”错误

nginx配置语法上没有错误的,只是系统无法解析这个域名,所以报错. 解决办法就是添加dns到/etc/resolv.conf 或者是/etc/hosts,让其能够解析到IP。具体步骤如下&#xff1a; vim /etc/hosts 修改hosts文件&#xff0c;在hosts文件里面加上一句 127.0.0.1 localhost.localdomain x…

SM4国密4在jdk1.7版本和jdk1.8版本中的工具类使用

&#xff08;一&#xff09;首先&#xff0c;直接可用的工具类如下&#xff1a; 1、JDK1.8版本&#xff0c;使用hutool工具类实现SM4对称加密&#xff0c;pom依赖如下&#xff1a; <!-- Hutool 工具包 --><dependency><groupId>cn.hutool</groupId><…

滤波器设计工具简介

目录 快速入门 设计滤波器 查看其他分析 更改轴单位 标记数据点 优化设计 更改分析参数 导出滤波器 生成 MATLAB 文件 量化滤波器 目标 其他功能 此示例说明如何使用方便的滤波器设计工具替代命令行滤波器设计函数。 滤波器设计工具是 Signal Processing Toolbox™…

SpringCloud复习:(1)netflix包里的DiscoveryClient类

DiscoveryClient类实现了EurekaClient接口 它的主要作用&#xff1a;服务注册&#xff0c;服务续约&#xff0c;服务下线&#xff0c;获取服务列表。 initScheduledTasks方法用来开启定时任务来完成上述功能。 上图中的代码用来从服务器定期&#xff08;默认30秒&#xff09;…

[黑马程序员SpringBoot2]——基础篇1

目录&#xff1a; SpringBoot入门案例&#xff08;Idea联网版&#xff09;SpringBoot入门案例&#xff08;官网创建版&#xff09;SpringBoot入门案例&#xff08;阿里云版&#xff09;SpringBoot入门案例&#xff08;手工制作版&#xff09;教你一招&#xff0c;隐藏文件或文件…

微信小程序——后台交互

目录 后台准备 pom.xml 配置数据源 整合mtbatis 前后端交互 method1 method2 后台准备 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org…

解决Vue 3 + Element Plus树形表格全选多选以及子节点勾选的问题

文章目录 问题描述解决方案1. 创建树形表格2. 实现全选功能3. 实现多选功能4. 实现子节点勾选5. 实现父节点勾选 结论 &#x1f389;欢迎来到Java学习路线专栏~解决Vue 3 Element Plus树形表格全选多选以及子节点勾选的问题 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博…

RabbitMQ运行机制和通讯过程介绍

文章目录 1.RabbitMQ 环境搭建2.RabbitMQ简介3.RabbitMQ的优势&#xff1a;4. rabbitmq服务介绍4.1 rabbitmq关键词说明4.2 消息队列运行机制4.3 exchange类型 5.wireshark抓包查看RabbitMQ通讯过程 1.RabbitMQ 环境搭建 参考我的另一篇&#xff1a;RabbitMQ安装及使用教程&am…

数据结构数组 Array 手写实现,扩容原理

数组数据结构 数组&#xff08;Array&#xff09;是一种线性表数据结构。它用一组连续的内存空间&#xff0c;来存储一组具有相同类型数据的集合。 数组的特点&#xff1a; 数组是相同数据类型的元素集合&#xff08;int 不能存放 double&#xff09;数组中各元素的存储是有先…

(免费领源码)php#mysql红色旅游网站99214-计算机毕业设计项目选题推荐

摘 要 21世纪时信息化的时代&#xff0c;几乎任何一个行业都离不开计算机&#xff0c;将计算机运用于旅游服务管理也是十分常见的。过去使用手工的管理方式对旅游服务进行管理&#xff0c;造成了管理繁琐、难以维护等问题&#xff0c;如今使用计算机对旅游服务的各项基本信息进…

2023年10月24日程序员节

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

Coreldraw2020最新64位电脑完整版本下载教程

安装之前所有的杀毒软件都要退出。无论是360&#xff0c;腾讯管家&#xff0c;或者电脑自带的安全中心&#xff0c;要不然会阻止安装。 CorelDRAW2020版win下载如下:https://wm.makeding.com/iclk/?zoneid55678 CorelDRAW2020版mac下载如下:https://wm.makeding.com/iclk/?…

linux下安装配置maven

一. 下载maven安装包 安装 maven 环境前&#xff0c;需要先安装 java 环境&#xff0c;笔者这里已经成功安装 java 环境&#xff0c;如果没有安装 java 环境&#xff0c;可以参考&#xff1a;https://blog.csdn.net/qq_44936392/article/details/133931321?spm1001.2014.3001.…

.net6部署到linux上(CentOS Linux 7)

目录 一、先在linux上配置.net环境 添加 Microsoft 包存储库 安装 SDK 安装运行时 检查 SDK 版本可使用终端查看当前安装的 .NET SDK 版本。 打开终端并运行以下命令。 二、创建.net6 mvc项目 并发布 创建项目 修改默认端口 打包发布到文件夹 运行打包项目查看项目是否…

redis 数据结构

一、为什么要扒一下底层技术 首先我是一个解决方案工程师&#xff0c;为什么要看redis底层的设计呢&#xff1f;总结下来分几点&#xff1a; 1. 让系统跑起来更放心 2. 面试中可以对跟对面的牛马侃大山、吹&#x1f42e; 3. 虚一点&#xff0c;举一反三&#xff0c;学习一下…