• CefSharp进阶


    本节说明一下如何调用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)

    1. html>
    2. <html lang="zh-CN">
    3. <head>
    4. <meta charset="utf-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1">
    7. <title>Bootstrap 101 Templatetitle>
    8. <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
    9. head>
    10. <body>
    11. <h1>你好,世界!h1>
    12. <button class="btn btn-info" onclick="cefCustomObject2.showDevTools();">浏览器调试工具button>
    13. <button class="btn btn-primary" onclick="cefCustomObject2.opencmd();">本地命令行工具button>
    14. <button class="btn btn-primary" id="test">对话框button>
    15. <button class="btn btn-primary" onclick="cefCustomObject2.ok()">确定button>
    16. <button class="btn btn-primary" onclick="findComputerInfo()">获取电脑信息button>
    17. <button class="btn btn-primary" onclick="cefCustomObject2.closeForm();">关闭窗体button>
    18. <ul id="msg">ul>
    19. <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
    20. Launch demo modal
    21. button>
    22. <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    23. <div class="modal-dialog" role="document">
    24. <div class="modal-content">
    25. <div class="modal-header">
    26. <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×span>button>
    27. <h4 class="modal-title" id="myModalLabel">Modal titleh4>
    28. div>
    29. <div class="modal-body">
    30. test
    31. div>
    32. <div class="modal-footer">
    33. <button type="button" class="btn btn-default" data-dismiss="modal">Closebutton>
    34. <button type="button" class="btn btn-primary">Save changesbutton>
    35. div>
    36. div>
    37. div>
    38. div>
    39. <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js">script>
    40. <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js">script>
    41. <script type="text/javascript">
    42. $(document).ready(function () {
    43. $('#test').on('click', function () {
    44. alert('test');
    45. });
    46. });
    47. //调用C#方法后的回调函数:显示电脑信息
    48. //data为C#方法返回的数据
    49. function callback(data) {
    50. data = JSON.parse(data);
    51. $("#msg").html('');
    52. $("#msg")
    53. .append($("
    54. cpu_id:" + data.cpu_id + "
    55. "))
  • .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的返回值

    1. using CefSharp;
    2. using CefSharp.WinForms;
    3. using Newtonsoft.Json;
    4. using System;
    5. using System.Collections.Generic;
    6. using System.Diagnostics;
    7. using System.Linq;
    8. using System.Text;
    9. using System.Threading.Tasks;
    10. using System.Windows.Forms;
    11. namespace cef1
    12. {
    13. public class CefCustomObject
    14. {
    15. // Declare a local instance of chromium and the main form in order to execute things from here in the main thread
    16. private static ChromiumWebBrowser _instanceBrowser = null;
    17. // The form class needs to be changed according to yours
    18. private static Form1 _instanceMainForm = null;
    19. public CefCustomObject(ChromiumWebBrowser originalBrowser, Form1 mainForm)
    20. {
    21. _instanceBrowser = originalBrowser;
    22. _instanceMainForm = mainForm;
    23. }
    24. ///
    25. /// 打开调试工具
    26. ///
    27. public void showDevTools()
    28. {
    29. _instanceBrowser.ShowDevTools();
    30. }
    31. ///
    32. /// 打开命令行工具
    33. ///
    34. public void opencmd()
    35. {
    36. ProcessStartInfo start = new ProcessStartInfo("cmd.exe", "/c pause");
    37. Process.Start(start);
    38. }
    39. public void ok()
    40. {
    41. MessageBox.Show("123");
    42. }
    43. ///
    44. /// 切换网页
    45. ///
    46. public void changePage()
    47. {
    48. _instanceBrowser.Load("www.163.com");
    49. }
    50. ///
    51. /// 关闭窗体
    52. ///
    53. public void closeForm()
    54. {
    55. try
    56. {
    57. _instanceBrowser.CloseDevTools();
    58. _instanceBrowser.GetBrowser().CloseBrowser(true);
    59. }
    60. catch { }
    61. try
    62. {
    63. if (_instanceBrowser != null)
    64. {
    65. _instanceBrowser.Dispose();
    66. }
    67. }
    68. catch { }
    69. if (!_instanceMainForm.IsDisposed && _instanceMainForm.IsHandleCreated)
    70. {
    71. var result = _instanceMainForm.BeginInvoke(new Action(() =>
    72. {
    73. if (_instanceMainForm != null && !_instanceMainForm.IsDisposed)
    74. {
    75. _instanceMainForm.Close();
    76. _instanceMainForm.Dispose();
    77. }
    78. }));
    79. _instanceMainForm.EndInvoke(result);
    80. }
    81. }
    82. ///
    83. /// 查找电脑信息
    84. ///
    85. ///
    86. public void FindComputerInfo(IJavascriptCallback javascriptCallback)
    87. {
    88. Task.Factory.StartNew(async () =>
    89. {
    90. using (javascriptCallback)
    91. {
    92. Computer computer = new Computer();
    93. string response = JsonConvert.SerializeObject(new
    94. {
    95. cpu_id = computer.CPU_Id,
    96. disk_id = computer.Disk_Id,
    97. host_name = computer.HostName,
    98. networkcard = computer.NetworkCard,
    99. serialNumber = computer.SerialNumber_Manufacturer_Product.Item1,
    100. manufacturer = computer.SerialNumber_Manufacturer_Product.Item2,
    101. product = computer.SerialNumber_Manufacturer_Product.Item3,
    102. });
    103. await javascriptCallback.ExecuteAsync(response);
    104. }
    105. });
    106. }
    107. }
    108. }

    3.建立访问Computer的类

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Management;
    5. using System.Text;
    6. using System.Threading.Tasks;
    7. namespace cef1
    8. {
    9. public class Computer
    10. {
    11. ///
    12. /// 查找cpu的id
    13. ///
    14. ///
    15. public string CPU_Id
    16. {
    17. get
    18. {
    19. try
    20. {
    21. string str = string.Empty;
    22. ManagementClass mcCPU = new ManagementClass("win32_Processor");
    23. ManagementObjectCollection mocCPU = mcCPU.GetInstances();
    24. foreach (ManagementObject m in mocCPU)
    25. {
    26. str = m["Processorid"].ToString().Trim().Substring(0, 8);
    27. break;
    28. }
    29. return str;
    30. }
    31. catch (Exception)
    32. {
    33. return string.Empty;
    34. }
    35. }
    36. }
    37. public string Disk_Id
    38. {
    39. get
    40. {
    41. try
    42. {
    43. string hdId = string.Empty;
    44. ManagementClass hardDisk = new ManagementClass("win32_DiskDrive");
    45. ManagementObjectCollection hardDiskC = hardDisk.GetInstances();
    46. foreach (ManagementObject m in hardDiskC)
    47. {
    48. hdId = m.Properties["Model"].Value.ToString();
    49. break;
    50. }
    51. return hdId;
    52. }
    53. catch (Exception)
    54. {
    55. return string.Empty;
    56. }
    57. }
    58. }
    59. ///
    60. /// 网卡
    61. ///
    62. public string NetworkCard
    63. {
    64. get
    65. {
    66. try
    67. {
    68. string MoAddress = string.Empty;
    69. ManagementClass networkAdapter = new ManagementClass("Win32_NetworkAdapterConfiguration");
    70. ManagementObjectCollection adapterC = networkAdapter.GetInstances();
    71. foreach (ManagementObject m in adapterC)
    72. {
    73. if ((bool)m["IPEnabled"] == true)
    74. {
    75. MoAddress = m["MacAddress"].ToString().Trim();
    76. m.Dispose();
    77. }
    78. }
    79. return MoAddress;
    80. }
    81. catch
    82. {
    83. return string.Empty;
    84. }
    85. }
    86. }
    87. ///
    88. /// 获取序列号,制造商,型号
    89. ///
    90. public Tuple<string, string, string> SerialNumber_Manufacturer_Product
    91. {
    92. get
    93. {
    94. try
    95. {
    96. Tuple<string, string, string> tuple = null; new Tuple<string, string, string>(string.Empty, string.Empty, string.Empty);
    97. ManagementObjectSearcher mos = new ManagementObjectSearcher("select * from Win32_baseboard");
    98. foreach (ManagementObject m in mos.Get())
    99. {
    100. tuple = new Tuple<string, string, string>(m["SerialNumber"].ToString(), m["Manufacturer"].ToString(), m["Product"].ToString());
    101. }
    102. return tuple;
    103. }
    104. catch (Exception)
    105. {
    106. return null;
    107. }
    108. }
    109. }
    110. ///
    111. /// 计算机名称
    112. ///
    113. public string HostName
    114. {
    115. get
    116. {
    117. return System.Net.Dns.GetHostName();
    118. }
    119. }
    120. }
    121. }

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

    1. using CefSharp;
    2. using System;
    3. using System.Collections.Generic;
    4. using System.Linq;
    5. using System.Text;
    6. using System.Threading.Tasks;
    7. namespace cef1
    8. {
    9. ///
    10. /// 屏蔽右键菜单
    11. ///
    12. public class MenuHandler : IContextMenuHandler
    13. {
    14. void CefSharp.IContextMenuHandler.OnBeforeContextMenu(CefSharp.IWebBrowser browserControl, CefSharp.IBrowser browser, CefSharp.IFrame frame, CefSharp.IContextMenuParams parameters, CefSharp.IMenuModel model)
    15. {
    16. model.Clear();
    17. }
    18. bool CefSharp.IContextMenuHandler.OnContextMenuCommand(CefSharp.IWebBrowser browserControl, CefSharp.IBrowser browser, CefSharp.IFrame frame, CefSharp.IContextMenuParams parameters, CefSharp.CefMenuCommand commandId, CefSharp.CefEventFlags eventFlags)
    19. {
    20. //throw new NotImplementedException();
    21. return false;
    22. }
    23. void CefSharp.IContextMenuHandler.OnContextMenuDismissed(CefSharp.IWebBrowser browserControl, CefSharp.IBrowser browser, CefSharp.IFrame frame)
    24. {
    25. //throw new NotImplementedException();
    26. }
    27. bool CefSharp.IContextMenuHandler.RunContextMenu(CefSharp.IWebBrowser browserControl, CefSharp.IBrowser browser, CefSharp.IFrame frame, CefSharp.IContextMenuParams parameters, CefSharp.IMenuModel model, CefSharp.IRunContextMenuCallback callback)
    28. {
    29. return false;
    30. }
    31. }
    32. }

    5.主界面的代码

    1. using CefSharp;
    2. using CefSharp.WinForms;
    3. using System;
    4. using System.Collections.Generic;
    5. using System.ComponentModel;
    6. using System.Data;
    7. using System.Drawing;
    8. using System.IO;
    9. using System.Linq;
    10. using System.Text;
    11. using System.Threading.Tasks;
    12. using System.Windows.Forms;
    13. namespace cef1
    14. {
    15. public partial class Form1 : Form
    16. {
    17. private ChromiumWebBrowser chromeBrowser;
    18. public Form1()
    19. {
    20. InitializeComponent();
    21. InitializeChromium();//初始化
    22. }
    23. private void Form1_Load(object sender, EventArgs e)
    24. {
    25. }
    26. public void InitializeChromium()
    27. {
    28. string indexpage = string.Format(@"{0}\html\html\index.html", Application.StartupPath);
    29. if (!File.Exists(indexpage))
    30. {
    31. MessageBox.Show("程序将要退出,本地网页文件不错在:" + indexpage);
    32. return;
    33. }
    34. CefSettings settings = new CefSettings();
    35. //Example of setting a command line argument
    36. //Enables WebRTC
    37. settings.CefCommandLineArgs.Add("enable-media-stream", "1");
    38. settings.CefCommandLineArgs.Add("no-proxy-server", "1");
    39. settings.CefCommandLineArgs.Add("proxy-server", "ProxyAddress");
    40. settings.CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache");
    41. Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);
    42. chromeBrowser = new ChromiumWebBrowser(indexpage);
    43. this.Controls.Add(chromeBrowser);
    44. chromeBrowser.Dock = DockStyle.Fill;
    45. chromeBrowser.MenuHandler = new MenuHandler();
    46. BrowserSettings browserSettings = new BrowserSettings();
    47. browserSettings.FileAccessFromFileUrls = CefState.Enabled;
    48. browserSettings.UniversalAccessFromFileUrls = CefState.Enabled;
    49. chromeBrowser.BrowserSettings = browserSettings;
    50. CefSharpSettings.LegacyJavascriptBindingEnabled = true;
    51. //在浏览器中注册一个javascript对象
    52. //BingdingOptions:Cefsharp版本必须大于63,否则会报错
    53. chromeBrowser.RegisterJsObject("cefCustomObject2", new CefCustomObject(chromeBrowser, this)); //cefCustomObject2和CefCustomObject关联上
    54. }
    55. private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    56. {
    57. Cef.Shutdown();
    58. }
    59. }
    60. }

     6.效果

    拓展

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

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

    只需要把下面的方法

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

    替换成即可

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

  • 相关阅读:
    WhatsApp个人号、Business号、API号到底有什么区别
    unr #6day1 T2题解
    算法与数据结构【30天】集训营——图的应用之最小生成树、最短路径、拓扑排序、关键路径(29)
    web大学生个人网站作业模板——上海旅游景点介绍网页代码 家乡旅游网页制作模板 大学生静态HTML网页源码...
    深入浅出 JavaScript 中的 this
    【Java 基础篇】Java日期和时间格式化与解析指南:SimpleDateFormat详解
    云边缘网关TG453
    虚拟环境中使用的Python不是当前虚拟环境的,解决方法
    web基础和http协议
    Java核心卷一 · 笔记05
  • 原文地址:https://blog.csdn.net/u012563853/article/details/126075821