CefSharp 是 .NET 平台基于 Chromium 的开源框架,适用于 Windows Forms 和 WPF 应用。

优点显而易见,是为数不多的桌面端 WEB 方案之一,基于 Chromium 本身的引擎特性,拥有目前最好的兼容性;缺点就是 CPU 和内存消耗较大,另外编译后磁盘容量占用也不小。

重点内容

  1. CefSharp 组件在编译时会检查平台,通常来讲 Any CPU 方案不可行的,需要指定平台为 x86 或是 x64。
  2. 目前版本中已经改变了对象的注入方式。

首次使用

1. 创建WinForms项目,并将项目属性设置为x86平台

可根据实际需要选择 x86 或 x64 平台。

2. 通过 Nuget 包管理器引用 CefSharp 组件

Nuget 包管理器安装 CefSharp.WinForms 包,会自动下载其他依赖的包。

3. 加载本地页面

新建窗体,并输入以下代码

private ChromiumWebBrowser _chromiumWebBrowser;

public LocalPageForm()
{
InitializeComponent();
Load += LocalPageForm_Load;
} private void LocalPageForm_Load(object sender, EventArgs e)
{
var localPage = Path.Combine(Environment.CurrentDirectory, "Pages", "new.html");
_chromiumWebBrowser = new ChromiumWebBrowser(localPage); //加载页面
_chromiumWebBrowser.Dock = DockStyle.Fill;
// 页面加载完毕后打开开发者工具
_chromiumWebBrowser.FrameLoadEnd += (s, eve) =>
{
var browser = _chromiumWebBrowser.GetBrowser();
browser.ShowDevTools();
};
JsObjectResolver(); // 新版本的注入方式
Controls.Add(_chromiumWebBrowser);
} private void JsObjectResolver()
{
// 由网页端 CefSharp.BindObjectAsync 触发
_chromiumWebBrowser.JavascriptObjectRepository.ResolveObject += (s, eve) =>
{
var repo = eve.ObjectRepository;
if (eve.ObjectName == "storeObj")
{
// 在 new.html 使用 storeObj 触发
repo.Register("storeObj", new Store(), isAsync: true);
}
};
}

加载本地页面需要在本地创建HTML页面(废话),以上图中 73 版本为例,在创建以下简单页面pages/new.html,并设置属性复制到输出目录:如果较新则复制

new.html page
<ul>
<li><button onclick="n()">新式调用</button></li>
</ul>
<script>
CefSharp.BindObjectAsync("storeObj"); //这里会触发Form端的ResolveObject事件
function n() {
// 注意异步方法的输出顺序
var r1 = storeObj.buy(15);
console.log(r1)
storeObj.sell().then((r2) => {
console.log(r2)
});
console.log("end");
}
</script>

4. 加载远程页面,并注入需要的脚本

_chromiumWebBrowser = new ChromiumWebBrowser("https://www.baidu.com");
_chromiumWebBrowser.Dock = DockStyle.Fill;
_chromiumWebBrowser.FrameLoadEnd += (s, eve) =>
{
var browser = _chromiumWebBrowser.GetBrowser();
browser.ShowDevTools(); var scritps = new string[] {
"var scr = document.createElement('script');",
"scr.type = 'text/javascript';",
"scr.src = 'https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.15/lodash.js';",
"document.head.appendChild(scr);"
}; _chromiumWebBrowser.EvaluateScriptAsync(string.Join(";", scritps));
MessageBox.Show("可在控制台中使用 _.VERSION 调用测试", "Loadsh.js 注入完成");
};
this.Controls.Add(_chromiumWebBrowser);

上述代码以百度为例,注入了 lodash.js 库(同时推荐一下这个工具脚本库)。

可以看到通过 EvaluateScriptAsync 方法去让页面执行指定的脚本,可以满足一些特殊需求。

写在最后

老版本的使用方法这里就不说了,目前网上能找到的大部分都是老版本的使用方法。

// 1. 旧版本的注入方式,从后端到前端,官方不建议使用(已过时)
CefSharpSettings.LegacyJavascriptBindingEnabled = true;
_chromiumWebBrowser.RegisterJsObject("obs", new TestClass());
// 页面无需绑定(因为是全局的) // 2. 新版本的注入方式,收到前端请求后再注入,官方推荐
_chromiumWebBrowser.JavascriptObjectRepository.ResolveObject += (s, eve) => {
var repo = eve.ObjectRepository;
if (eve.ObjectName == "storeObj")
{
repo.Register("storeObj", new Store(), isAsync: true);
}
}
// 2.1 页面绑定
CefSharp.BindObjectAsync("storeObj");

示例相关源码可查看Github仓库:https://github.com/CoyoIsLove/Simple.CefSharp

[CefSharp] 如何在JavaScript中调用C#代码的更多相关文章

  1. 如何在Java中调用Python代码

    有时候,我们会碰到这样的问题:与A同学合作写代码,A同学只会写Python,而不会Java, 而你只会写Java并不擅长Python,并且发现难以用Java来重写对方的代码,这时,就不得不想方设法“调 ...

  2. JAVAFX 2.0 javascript中调用java代码

    现在你已经知道如何在JavaFX中调用JavaScript.在本章中,你将了解到相反的功能——在web页面中调用JavaFX. 大体上的理念是在JavaFX程序中创建一个接口对象,并通过调用JSObj ...

  3. 一步一步学Silverlight 2系列(21):如何在Silverlight中调用JavaScript

    概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  4. 在Java中调用Python代码

    极少数时候,我们会碰到类似这样的问题:与A同学合作写代码, A同学只会写Python,不熟悉Java ,而你只会写Java不擅长Python,并且发现难以用Java来重写对方的代码,这时,就不得不想方 ...

  5. ios中javascript直接调用oc代码而非通过改变url回调方式(转)

    之前一个ios项目中,需要通过UIWebview来打开一个静态页面,并在静态页面中 调用相关object-c代码. 一.以前使用js调用object-c的方法 关于如何使用javascript调用ob ...

  6. 如何在python中调用C语言代码

    1.使用C扩展CPython还为开发者实现了一个有趣的特性,使用Python可以轻松调用C代码 开发者有三种方法可以在自己的Python代码中来调用C编写的函数-ctypes,SWIG,Python/ ...

  7. 如何实现 javascript “同步”调用 app 代码

    在 App 混合开发中,app 层向 js 层提供接口有两种方式,一种是同步接口,一种一异步接口(不清楚什么是同步的请看这里的讨论).为了保证 web 流畅,大部分时候,我们应该使用异步接口,但是某些 ...

  8. vs2013如何在C++中调用Lua(二)

    Lua学习笔记 vs2013如何在C++中调用Lua (此为转载教程) 本人试过完全可行 一.准备工作 1.下载Lua源码,地址:http://www.lua.org/download.html(我用 ...

  9. COM动态添加删除成员,类似JavaScript中调用的对象

    在JavaScript中调用对象时,可动态添加删除成员如: var obj=new Object; obj.member1='aaaaa'; obj.fun1=function() { alert(' ...

随机推荐

  1. BUPT2017 springtraining(15) #3

    这里这里 A.签到题 #include <cstdio> double a[] = {0.4, 0.16, 0.063, 0.025, 0.010, 0.004}; int main() ...

  2. HDU 5442 Favorite Donut

    Favorite Donut Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  3. noip模拟赛 希望

    分析:题目中说用栈实现,我觉得这样很麻烦,就用了一个数组+指针解决了.其实就是大模拟. #include <stack> #include <string> #include ...

  4. nyoj_19_擅长排列的小明_201403011600

    擅长排列的小明时间限制:1000 ms  |  内存限制:65535 KB 难度:4描述 小明十分聪明,而且十分擅长排列计算.比如给小明一个数字5,他能立刻给出1-5按字典序的全排列,如果你想为难他, ...

  5. gh-ost 号称是不需要触发器(Triggerless)支持的在线更改表结构的工具

    https://segmentfault.com/a/1190000006158503?utm_source=tuicool&utm_medium=referral

  6. shell EOF注意点

    当sqlplus与shell交互的时候我们这么用 su - oracle -c "sqlplus / as sysdba<<EOF select * from gv($insta ...

  7. POJ 2375 Cow Ski Area(强连通)

    POJ 2375 Cow Ski Area id=2375" target="_blank" style="">题目链接 题意:给定一个滑雪场, ...

  8. crm使用FetchXml分组聚合查询

    /* 创建者:菜刀居士的博客  * 创建日期:2014年07月09号  */ namespace Net.CRM.FetchXml {     using System;     using Micr ...

  9. 10.3arcmap矢量数据制作步骤

    注意:在制作之前需要点将图放到原本大小.并且保存一下不然容易造成数据丢失. 在数据制作之前需要新建一个页面,用来放需要处理的原始数据 勾选ArcMap中Customize——ArcMap Option ...

  10. Android+Jquery Mobile学习系列(9)-总结和代码分享

    经过一个多月的边学习边练手,学会了Android基于Web开发的毛皮,其实开发过程中用Android原生API不是很多,更多的是HTML/Javascript/Css. 个人觉得基于WebView的J ...