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. 【Codeforces 1106D】Lunar New Year and a Wander

    [链接] 我是链接,点我呀:) [题意] 让你遍历n个节点,访问过的节点不操作. 如果是没有访问过的点,那就把它加到序列的末尾. 问你形成的最小字典序的序列是多少. [题解] 显然每次找最小的标号 用 ...

  2. 【codeforces 508C】Anya and Ghosts

    [题目链接]:http://codeforces.com/contest/508/problem/C [题意] 每秒钟可以点一根蜡烛; 这根蜡烛会燃烧t秒; 然后会有m只鬼来拜访你; 要求在鬼来拜访你 ...

  3. ReportNG 替换testng获得测试报告

    1.导入reportng相关jar包

  4. ZooKeeper之初识

    它是什么 俗称动物管理员,它使用java开发,开源,接口简单,高效,稳定的分布式系统,为其它分布式系统提供协调服务 为什么会存在? 开发分布式系统跟单机上做开发完全不同,碰到的问题完全不同,开发分布式 ...

  5. SSH框架之Struts(3)——Struts的执行流程之核心方法

    上篇讲了Tomcat实例化一个单例的ActionServlet.依据web.xml配置文件做好对应的初始化工作. 这时client产生一个.do结尾的request请求,採用get/post方式提交之 ...

  6. [Mini Program] 尺寸单位 rpx

    So each phone's width is 750rpx. And according to the device ratio (width:height), we can calucalate ...

  7. 大型项目开发: 隔离 (《大规模C++程序设计》书摘)

    书中第六章 隔离. 主要在撰述什么须要定义在头文件?什么应当移到编译单元中? 核心仍然是先区分接口定义与实现细节.实现细节的改变会导致客户代码的又一次编译,从逻辑上也表示与客户代码间可能存在着强耦合. ...

  8. luogu2746 校园网

    题目大意: 一些学校连入一个电脑网络.那些学校已订立了协议:每个学校都会给其它的一些学校分发软件(称作“接受学校”).注意即使 B 在 A 学校的分发列表中, A 也不一定在 B 学校的列表中. 你要 ...

  9. maven工程读取resource下配置文件

    maven工程读取resource下配置文件 在maven工程中,我们会将配置文件放到,src/main/resources   下面,例如 我们需要确认resource 下的文件 编译之后存放的位置 ...

  10. kafka的topic和分区策略——log entry和消息id索引文件

    Topic在逻辑上可以被认为是一个在的queue,每条消费都必须指定它的topic,可以简单理解为必须指明把这条消息放进哪个queue里. 为了使得Kafka的吞吐率可以水平扩展,物理上把topic分 ...