本节说明一下如何调用HTML网页以及和c#交互的问题。
使用的环境vs2022,.NET Framework4.8,cefsharp版本75.1.143。
首先环境问题参考上一篇,CefSharp入门-winform_故里2130的博客-CSDN博客。
软件系统运行流程:
总体项目文件预览:
1.首先我们找一个正常能运行的web网站
运行后的效果
HTML代码
1.如果调用c#中类的方法,无返回值的话,可以直接调用,js中不需要写调用的代码,例如:cefCustomObject2.ok()
2.如果调用c#中类的方法,有返回值的话,需要在js中声明方法,然后接收返回的值,并且进行格式化输出,例如:findComputerInfo(),callback(data)
- 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">
-
- <title>Bootstrap 101 Templatetitle>
-
-
- <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
-
-
-
-
- head>
- <body>
- <h1>你好,世界!h1>
-
- <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 type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
- Launch demo modal
- button>
-
-
- <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">×span>button>
- <h4 class="modal-title" id="myModalLabel">Modal titleh4>
- div>
- <div class="modal-body">
- test
- div>
- <div class="modal-footer">
- <button type="button" class="btn btn-default" data-dismiss="modal">Closebutton>
- <button type="button" class="btn btn-primary">Save changesbutton>
- div>
- div>
- div>
- div>
-
-
- <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js">script>
-
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/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($("
- cpu_id:"
+ data.cpu_id + "")) - .append($("
- disk_id:"
+ data.disk_id + "")) - .append($("
- host_name:"
+ data.host_name + "")) - .append($("
- networkcard:"
+ data.networkcard + "")) - .append($("
- serialNumber:"
+ data.serialNumber + "")) - .append($("
- manufacturer:"
+ data.manufacturer + "")) - .append($("
- product:"
+ data.product + "")); - };
-
- 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;
- }
-
- ///
- /// 打开调试工具
- ///
- public void showDevTools()
- {
- _instanceBrowser.ShowDevTools();
- }
-
- ///
- /// 打开命令行工具
- ///
- public void opencmd()
- {
- ProcessStartInfo start = new ProcessStartInfo("cmd.exe", "/c pause");
- Process.Start(start);
- }
- public void ok()
- {
- MessageBox.Show("123");
- }
- ///
- /// 切换网页
- ///
- public void changePage()
- {
- _instanceBrowser.Load("www.163.com");
- }
-
- ///
- /// 关闭窗体
- ///
- 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);
- }
-
- }
-
- ///
- /// 查找电脑信息
- ///
- ///
- 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
- {
- ///
- /// 查找cpu的id
- ///
- ///
- 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;
- }
- }
- }
- ///
- /// 网卡
- ///
- 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;
- }
- }
- }
- ///
- /// 获取序列号,制造商,型号
- ///
- 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;
- }
- }
- }
- ///
- /// 计算机名称
- ///
- 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
- {
- ///
- /// 屏蔽右键菜单
- ///
- 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.效果
拓展
如果把cefsharp的版本换成83.4.20时,会有如下报错
根据提示打开对应的网址,之前的方法已经弃用了,需要使用新的方法。
只需要把下面的方法
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);