CefSharp实战演示

CefSharp实战演示

本节说明一下如何调用HTML网页以及和c#交互的问题。

使用的环境vs2022,.NET Framework4.8,cefsharp版本75.1.143。

首先环境问题参考上一篇,。

软件系统运行流程:

www.zeeklog.com - CefSharp实战演示

总体项目文件预览:

www.zeeklog.com - CefSharp实战演示

1.首先我们找一个正常能运行的web网站

www.zeeklog.com - CefSharp实战演示

运行后的效果

www.zeeklog.com - CefSharp实战演示

HTML代码

1.如果调用c#中类的方法,无返回值的话,可以直接调用,js中不需要写调用的代码,例如:cefCustomObject2.ok()

2.如果调用c#中类的方法,有返回值的话,需要在js中声明方法,然后接收返回的值,并且进行格式化输出,例如:findComputerInfo(),callback(data)

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <title>Bootstrap 101 Template</title> <!-- Bootstrap --> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> <!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 --> <!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 --> <!--[if lt IE 9]> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/html5shiv.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dest/respond.min.js"></script> <![endif]--> </head> <body> <h1>你好,世界!</h1> <!--这里的cefCustomObject2和FrmMain中RegisterJsObject方法的参数是一致的,关联作用--> <button class="btn btn-info" onclick="cefCustomObject2.showDevTools();">浏览器调试工具</button> <button class="btn btn-primary" onclick="cefCustomObject2.opencmd();">本地命令行工具</button> <button class="btn btn-primary" id="test">对话框</button> <button class="btn btn-primary" onclick="cefCustomObject2.ok()">确定</button> <button class="btn btn-primary" onclick="findComputerInfo()">获取电脑信息</button> <button class="btn btn-primary" onclick="cefCustomObject2.closeForm();">关闭窗体</button> <ul id="msg"></ul> <!-- Button trigger modal --> <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal"> Launch demo modal </button> <!-- Modal --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> <h4 class="modal-title" id="myModalLabel">Modal title</h4> </div> <div class="modal-body"> test </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div> </div> </div> <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) --> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script> <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 --> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script> <script type="text/javascript"> $(document).ready(function () { $('#test').on('click', function () { alert('test'); }); }); //调用C#方法后的回调函数:显示电脑信息 //data为C#方法返回的数据 function callback(data) { data = JSON.parse(data); $("#msg").html(''); $("#msg") .append($("<li>cpu_id:" + data.cpu_id + "</li>")) .append($("<li>disk_id:" + data.disk_id + "</li>")) .append($("<li>host_name:" + data.host_name + "</li>")) .append($("<li>networkcard:" + data.networkcard + "</li>")) .append($("<li>serialNumber:" + data.serialNumber + "</li>")) .append($("<li>manufacturer:" + data.manufacturer + "</li>")) .append($("<li>product:" + data.product + "</li>")); }; function findComputerInfo() { //调用后台C#FindComputerInfo,返回结果回调方法callback 这里的cefCustomObject2和FrmMain中RegisterJsObject方法的参数是一致的,关联作用 cefCustomObject2.findComputerInfo(callback); }; </script> </body> </html>

2. 建立HTML界面和c#后台交互的CefCustomObject类

此处注意javascriptCallback,他是来自HTML的返回值

using CefSharp; using CefSharp.WinForms; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace cef1 { public class CefCustomObject { // Declare a local instance of chromium and the main form in order to execute things from here in the main thread private static ChromiumWebBrowser _instanceBrowser = null; // The form class needs to be changed according to yours private static Form1 _instanceMainForm = null; public CefCustomObject(ChromiumWebBrowser originalBrowser, Form1 mainForm) { _instanceBrowser = originalBrowser; _instanceMainForm = mainForm; } /// <summary> /// 打开调试工具 /// </summary> public void showDevTools() { _instanceBrowser.ShowDevTools(); } /// <summary> /// 打开命令行工具 /// </summary> public void opencmd() { ProcessStartInfo start = new ProcessStartInfo("cmd.exe", "/c pause"); Process.Start(start); } public void ok() { MessageBox.Show("123"); } /// <summary> /// 切换网页 /// </summary> public void changePage() { _instanceBrowser.Load("www.163.com"); } /// <summary> /// 关闭窗体 /// </summary> public void closeForm() { try { _instanceBrowser.CloseDevTools(); _instanceBrowser.GetBrowser().CloseBrowser(true); } catch { } try { if (_instanceBrowser != null) { _instanceBrowser.Dispose(); } } catch { } if (!_instanceMainForm.IsDisposed && _instanceMainForm.IsHandleCreated) { var result = _instanceMainForm.BeginInvoke(new Action(() => { if (_instanceMainForm != null && !_instanceMainForm.IsDisposed) { _instanceMainForm.Close(); _instanceMainForm.Dispose(); } })); _instanceMainForm.EndInvoke(result); } } /// <summary> /// 查找电脑信息 /// </summary> /// <param name="javascriptCallback"></param> public void FindComputerInfo(IJavascriptCallback javascriptCallback) { Task.Factory.StartNew(async () => { using (javascriptCallback) { Computer computer = new Computer(); string response = JsonConvert.SerializeObject(new { cpu_id = computer.CPU_Id, disk_id = computer.Disk_Id, host_name = computer.HostName, networkcard = computer.NetworkCard, serialNumber = computer.SerialNumber_Manufacturer_Product.Item1, manufacturer = computer.SerialNumber_Manufacturer_Product.Item2, product = computer.SerialNumber_Manufacturer_Product.Item3, }); await javascriptCallback.ExecuteAsync(response); } }); } } } 

3.建立访问Computer的类

using System; using System.Collections.Generic; using System.Linq; using System.Management; using System.Text; using System.Threading.Tasks; namespace cef1 { public class Computer { /// <summary> /// 查找cpu的id /// </summary> /// <returns></returns> public string CPU_Id { get { try { string str = string.Empty; ManagementClass mcCPU = new ManagementClass("win32_Processor"); ManagementObjectCollection mocCPU = mcCPU.GetInstances(); foreach (ManagementObject m in mocCPU) { str = m["Processorid"].ToString().Trim().Substring(0, 8); break; } return str; } catch (Exception) { return string.Empty; } } } public string Disk_Id { get { try { string hdId = string.Empty; ManagementClass hardDisk = new ManagementClass("win32_DiskDrive"); ManagementObjectCollection hardDiskC = hardDisk.GetInstances(); foreach (ManagementObject m in hardDiskC) { hdId = m.Properties["Model"].Value.ToString(); break; } return hdId; } catch (Exception) { return string.Empty; } } } /// <summary> /// 网卡 /// </summary> public string NetworkCard { get { try { string MoAddress = string.Empty; ManagementClass networkAdapter = new ManagementClass("Win32_NetworkAdapterConfiguration"); ManagementObjectCollection adapterC = networkAdapter.GetInstances(); foreach (ManagementObject m in adapterC) { if ((bool)m["IPEnabled"] == true) { MoAddress = m["MacAddress"].ToString().Trim(); m.Dispose(); } } return MoAddress; } catch { return string.Empty; } } } /// <summary> /// 获取序列号,制造商,型号 /// </summary> public Tuple<string, string, string> SerialNumber_Manufacturer_Product { get { try { Tuple<string, string, string> tuple = null; new Tuple<string, string, string>(string.Empty, string.Empty, string.Empty); ManagementObjectSearcher mos = new ManagementObjectSearcher("select * from Win32_baseboard"); foreach (ManagementObject m in mos.Get()) { tuple = new Tuple<string, string, string>(m["SerialNumber"].ToString(), m["Manufacturer"].ToString(), m["Product"].ToString()); } return tuple; } catch (Exception) { return null; } } } /// <summary> /// 计算机名称 /// </summary> public string HostName { get { return System.Net.Dns.GetHostName(); } } } } 

4.建立右键屏蔽按钮MenuHandler的类

using CefSharp; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace cef1 { /// <summary> /// 屏蔽右键菜单 /// </summary> public class MenuHandler : IContextMenuHandler { void CefSharp.IContextMenuHandler.OnBeforeContextMenu(CefSharp.IWebBrowser browserControl, CefSharp.IBrowser browser, CefSharp.IFrame frame, CefSharp.IContextMenuParams parameters, CefSharp.IMenuModel model) { model.Clear(); } bool CefSharp.IContextMenuHandler.OnContextMenuCommand(CefSharp.IWebBrowser browserControl, CefSharp.IBrowser browser, CefSharp.IFrame frame, CefSharp.IContextMenuParams parameters, CefSharp.CefMenuCommand commandId, CefSharp.CefEventFlags eventFlags) { //throw new NotImplementedException(); return false; } void CefSharp.IContextMenuHandler.OnContextMenuDismissed(CefSharp.IWebBrowser browserControl, CefSharp.IBrowser browser, CefSharp.IFrame frame) { //throw new NotImplementedException(); } bool CefSharp.IContextMenuHandler.RunContextMenu(CefSharp.IWebBrowser browserControl, CefSharp.IBrowser browser, CefSharp.IFrame frame, CefSharp.IContextMenuParams parameters, CefSharp.IMenuModel model, CefSharp.IRunContextMenuCallback callback) { return false; } } } 

5.主界面的代码

using CefSharp; using CefSharp.WinForms; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace cef1 { public partial class Form1 : Form { private ChromiumWebBrowser chromeBrowser; public Form1() { InitializeComponent(); InitializeChromium();//初始化 } private void Form1_Load(object sender, EventArgs e) { } public void InitializeChromium() { string indexpage = string.Format(@"{0}\html\html\index.html", Application.StartupPath); if (!File.Exists(indexpage)) { MessageBox.Show("程序将要退出,本地网页文件不错在:" + indexpage); return; } CefSettings settings = new CefSettings(); //Example of setting a command line argument //Enables WebRTC settings.CefCommandLineArgs.Add("enable-media-stream", "1"); settings.CefCommandLineArgs.Add("no-proxy-server", "1"); settings.CefCommandLineArgs.Add("proxy-server", "ProxyAddress"); settings.CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache"); Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null); chromeBrowser = new ChromiumWebBrowser(indexpage); this.Controls.Add(chromeBrowser); chromeBrowser.Dock = DockStyle.Fill; chromeBrowser.MenuHandler = new MenuHandler(); BrowserSettings browserSettings = new BrowserSettings(); browserSettings.FileAccessFromFileUrls = CefState.Enabled; browserSettings.UniversalAccessFromFileUrls = CefState.Enabled; chromeBrowser.BrowserSettings = browserSettings; CefSharpSettings.LegacyJavascriptBindingEnabled = true; //在浏览器中注册一个javascript对象 //BingdingOptions:Cefsharp版本必须大于63,否则会报错 chromeBrowser.RegisterJsObject("cefCustomObject2", new CefCustomObject(chromeBrowser, this)); //cefCustomObject2和CefCustomObject关联上 } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { Cef.Shutdown(); } } } 

6.效果

www.zeeklog.com - CefSharp实战演示
www.zeeklog.com - CefSharp实战演示

拓展

如果把cefsharp的版本换成83.4.20时,会有如下报错

www.zeeklog.com - CefSharp实战演示

根据提示打开对应的网址,之前的方法已经弃用了,需要使用新的方法。

只需要把下面的方法

chromeBrowser.RegisterJsObject("cefCustomObject2", new CefCustomObject(chromeBrowser, this)); //cefCustomObject2和CefCustomObject关联上

替换成即可

 CefSharpSettings.LegacyJavascriptBindingEnabled = true; CefSharpSettings.WcfEnabled = true; chromeBrowser.JavascriptObjectRepository.Register("cefCustomObject2", new CefCustomObject(chromeBrowser, this), isAsync: false, options: BindingOptions.DefaultBinder);

来源:

Read more

使用 VS Code 连接 MySQL 数据库

使用 VS Code 连接 MySQL 数据库

文章目录 * 前言 * VS Code下载安装 * 如何在VS Code上连接MySQL数据库 * 1、打开扩展 * 2、安装MySQL插件 * 3、连接 * 导入和导出表结构和数据 前言 提示:这里可以添加本文要记录的大概内容: 听说VS Code不要钱,功能还和 Navicat 差不多,还能在上面打游戏 但是没安装插件是不行的 发现一个非常牛的博主 还有一个非常牛的大佬 提示:以下是本篇文章正文内容,下面案例可供参考 VS Code下载安装 VS Code下载安装 如何在VS Code上连接MySQL数据库 本篇分享是在已有VS Code这个软件的基础上,数据库举的例子是MySQL 1、打开扩展 2、安装MySQL插件 在搜索框搜索 MySQL和 MySQL Syntax,下载这三个插件 点击下面的插件,选择【install】安装

By
RustFS 保姆级上手指南:国产开源高性能对象存储

RustFS 保姆级上手指南:国产开源高性能对象存储

最近在给项目选型对象存储的时候,发现一个挺有意思的现象:一边是MinIO社区版功能逐渐“躺平”,另一边是大家对存储性能和安全性的要求越来越高。就在这时,一个叫 RustFS 的国产开源项目闯入了我的视野。 折腾了一阵子后,我感觉这玩意儿确实有点东西。它用Rust语言写,天生就带着高性能和内存安全的基因,性能号称比MinIO快一大截,而且用的是对商业友好的Apache 2.0协议。今天,我就手把手带大家从零开始,搭建一个属于自己的RustFS服务,体验一下国产存储的威力。 一、 RustFS是什么?为什么值得你关注? 简单说,RustFS是一个 分布式对象存储系统 。你可以把它理解成一个你自己搭建的、功能跟阿里云OSS、亚马逊S3几乎一样的“私有云盘”。 但它有几个非常突出的亮点,让我觉得必须试试: * 性能猛兽 :基于Rust语言开发,没有GC(垃圾回收)带来的性能抖动,官方数据显示在4K随机读场景下,性能比MinIO高出40%以上,内存占用还不到100MB,简直是“小钢炮”。 * 100%S3兼容 :这意味着你现有的所有使用S3 API的代码、工具(比如AWS

By