Winform下CefSharp的引用、配置、实例与报错排除(源码)
Winform 下 CefSharp 的引用, 配置, 实例与报错排除
[TOC]
1, 关于 CefSharp
装一手, 比较简单的英语Itisa wrapper around theChromiumEmbeddedFramework(CEF).About30%of the bindings are writteninC++/CLIwiththe majority of code hereisC#. It can be used from C# or VB, or any other CLR language. CefSharp provides both WPF and WinForms web browser control implementations.
CefSharpisBSD licensed,so it can be usedinboth proprietaryandfree/open source full details,see the LICENSE file.
自己总结的:
CefShar 是一个提供了 Chromium Embedded Framework (CEF) 的. NET 接口的开源项目, 提供了 Winform,WPF 封装, 可以用来代替微软的 WebBrowser, 浏览网页, 尤为强大的是实现了 C#,VB 等 vs 支持的语言与 JavaScript 的交互方法.
2,CefSharp 项目源码下载
源码下载 目前最新 v53.0.1 /cefsharp/CefSharp
源码结构介绍 http:///201805/
3,Winfrom 项目引入 CefSharp
我的开发环境 vs2013,.net4.0,Nugget 中搜索 CefSharp 显示的版本是 v53, 然而
v51.0.0-pre01
的 Breaking Changes 里面有这么一句
不想安装. net4.5.2, 所以只能通过
工具 - 程序包管理器 - 程序包管理控制台
手动命令行导入版本 v49.0.1 的, 输入命令
Install-Package -Version 49.0.1
回车等待执行完成, 我这里已经安装过了.
其他版本命令请参考.
等待导入成功, 生成一下... 报错...
嗯?!!!
如果你以为只是在
项目名右击 - 属性 - 生成 - 目标平台
改为 x86 就太天真了.... 反正我试了不行... 正确的姿 zhi 势 shi:
解决方案名右击 - 属性 - 配置属性 - 配置
, 右边平台选择 x86 或 x64, 什么? 选不到?
点击当前界面右上角
配置管理器 - 活动解决方案平台
下拉
新建
,x86/x64 随便选, 回来这边下拉已经可以选择了, 完事左下角确定, 再生成一下试试吧
以上看不懂的参考这里
4,Winfrom 下 CefSharp 的基本使用
4.1 显示一个页面
4.1.1 显示 url 网页
对照下面在一个 Form 的对应位置添加代码;
publicpartialclassForm1:Form
{
ChromiumWebBrowserwebBrower=null;
publicForm1()
{
InitializeComponent();
Load+=Form_Load;
}
privatevoidForm_Load(objectsender,EventArgse)
{
stringpath="";
webBrower=newChromiumWebBrowser(path);
=;// 填充方式
(webBrower);
}
}
直接运行就 OK 了
4.1.2 显示一个本地 html
把 path 改为 File 协议就行, 例如: 显示程序下的文件夹 html 中的 // 获取文件的物理路径
stringpath=+"\\html\\";
// 转换为 File 协议路径
path="file://"+("\\","/");
如果实在不知道怎么写的话, 建议直接用浏览器把 html 打开, 地址栏里面显示的 file:// 链接就是 File 协议路径
推荐个 CCS3 动画的 html, 直接右击保存到本地就行了, 修改完成, 同样运行就可以看到页面了, 运行还是挺流畅的.
4.2 JavaScript 调用异步 C# 方法
走弯路后的说明: BoundObject 等这三个类以及里面的方法都是可以自己任意定义实现的, 和普通的方法类没有太大区别, 没有必要去源码中拷过来.
从源码的
中找到三个类 BoundObject,SubBoundObject,ExceptionTestBoundObject 的源码拷过来, 记得对应着自己的项目把命名空间名改了.
如果是. net4.0,TestCallback,TestCallbackException 两个方法有提示 async/await, 的报错, 处理方式:
直接升级到. NET Framework 4.5: 从用户安装便捷性上讲, 个人感觉完全没必要
直接修改掉, 因为这是测试的代码, 可自己写不用 , 详情请参阅, ; 如果是想在. net4.0 下使用 async/await 还有别的方法 - 直接 Nuget 搜索安装 , 如果搜索太慢或者搜索不到可以直接在 nuget 控制台执行
Install-Package
. 如果和我一样提示 Nuget 版本 2.7 太低, 至少需要 2.8 的, 需要卸载升级 Nuget, 步骤:
卸载: 打开
VS-打开菜单 "工具"-"扩展管理器"-选择 "NuGet Package Manager"-点击 "卸载"
, 然后会提示重启, 不自动重启的话可以自己手动重启
下载新版本 nuget{aa7aa}, 根据你的 vs 版本选择下载后缀是. vsix, 直接安装就行, 装完最好再重启一下 vs.
我这里选择不升级. net 4.5 后面一种方法, 同时安装 .
这里实现的是一个延时回调的例子, 即点一个按钮, 调用绑定的 C# 方法在 3 秒后显示一条消息同时调用 js 方法立即显示一条消息.
测试内容准备:
BoundObject 中定义回调方法 (可以自己定义一个空的 BoundObject 类, 增加一下内容)publicvoidTestCallback(IJavascriptCallbackjavascriptCallback)
{
//.net 4.0 的写法
constinttaskDelay=3000;
(async()=>
{
Delay(taskDelay);
using(javascriptCallback)
{
//var response = new CallbackResponseStruct("This callback from C# was delayed" + taskDelay + "ms");
("来自 C# 的返回值, 在当前延迟"+taskDelay+"ms");
}
});
/*//.net 4.5 的写法
const int taskDelay = 1500;
(async () =>
{
await (taskDelay);
using (javascriptCallback)
{
//NOTE: Classes are not supported, simple structs are
var response = new CallbackResponseStruct("This callback from C# was delayed" + taskDelay + "ms");
await (response);
}
});
*/
}
在 Form 中给 ChromiumWebBrowser 增加绑定, 第三个参数 false 忽略方法名大小写建议不要忘记, 否则 JS 中掉用时方法名默认区分大小写
("bound", new BoundObject(),false);
新建个 html,body 中录入一下内容
Javascript Callback Test
functioncallback(s){
varresult=('show');
+="callback 返回值:"+()+"时间:"+Date();
}
functionTestCallback(){
// 调用后台 C# 方法 TestCallback, 返回结果回调方法 callback
(callback);
varresult=('show');
="方法返回 时间:"+Date()+"\n";
//("");
}
TestCallBakck
可以运行一下了, 点击一下
TestCallBakck
按钮, 会首先显示一行内容与时间, 3 秒后显示第二行内容.
4.3 JavaScript 调用带参数 C# 方法
准备内容:
BoundObject 添加 Repeat 方法publicstringRepeat(stringstr,intn)
{
stringresult=;
for(inti=0;i
{
result+=str;
}
returnresult;
}
html 内容
带参数调用 C# repeat 方法
varresult=("hello",6);
("content").innerHTML=""+result+"";
执行结果
4.4 JavaScript 调用委托 C# 方法
这里将一个方法 ReturnJsonEmployeeList 作为参数进行传递, 并返回一个 json 数据进行解析展示
BoundObject 中添加方法publicstringReturnJsonEmployeeList()
{
return"{\"employees\":[{\"firstName\":\"John\", \"lastName\":\"Doe\"},{\"firstName\":\"Anna\", \"lastName\":\"Smith\"},{\"firstName\":\"Peter\", \"lastName\":\"Jones\"}]}";
}
html 内容
委托 C# 方法 - 返回 json 字符串
functionmyfunc(fucPara){
returnfucPara();
}
varres=myfunc();
("委托输出结果:"+res+"
");
varjson=(res);//eval("'"+ res+"'");
("employees 数量:"++"
");
("[0].lastName :"+[0].lastName);
运行结果:
4.5 JavaScript 调用 C# 返回实体对象
准备内容
新建类 SubBoundObject, 对照添加以下内容publicclassSubBoundObject
{
publicstringSimpleProperty{get;set;}
publicSubBoundObject()
{
SimpleProperty="This is a very simple property.";
}
publicstringGetMyType()
{
return"My Type is"+GetType();
}
publicstringEchoSimpleProperty()
{
returnSimpleProperty;
}
}
BoundObject 中添加内容publicSubBoundObjectSubObject{
get;
set;
}
publicSubBoundObjectGetSubObject(){
returnSubObject;
}
html 中添加内容
返回实体对象
("().SimpleProperty :"+().SimpleProperty);
运行结果:
4.6 ChromiumWebBrowser 控件扩展 IContextMenuHandler 接口实现禁用右击按钮菜单
禁用右击菜单需要创建一个类实现接口 IContextMenuHandler, 然后把这个类赋值给 ChromiumWebBrowser 的 MenuHandler 即可. 这里创建类 MenuHandler:internalclassMenuHandler:IContextMenuHandler
{
publicvoidOnBeforeContextMenu(IWebBrowserbrowserControl,IBrowserbrowser,IFrameframe,IContextMenuParamsparameters,IMenuModelmodel)
{
();
}
publicboolOnContextMenuCommand(IWebBrowserbrowserControl,IBrowserbrowser,IFrameframe,IContextMenuParamsparameters,CefMenuCommandcommandId,CefEventFlagseventFlags)
{
returnfalse;
}
publicvoidOnContextMenuDismissed(IWebBrowserbrowserControl,IBrowserbrowser,IFrameframe)
{
}
publicboolRunContextMenu(IWebBrowserbrowserControl,IBrowserbrowser,IFrameframe,IContextMenuParamsparameters,IMenuModelmodel,IRunContextMenuCallbackcallback)
{
returnfalse;
}
}
配置到 ChromiumWebBrowser:
= new ();
这里只是禁用了菜单, 也可以在相关事件里面增加内容, 实现自定义右击菜单, 不同页面的不同右击菜单.
4.6 WebGL 页面渲染
使用 WebGL 可以实现很炫的页面效果, 以下这些实例都可以直接应用到一个引入了 CefSharp 的 WinFrom 桌面程序上面.
5, 依赖项
5.1 必需的运行环境
CefSharp 官方文件 中有以下要求:
根据 X86/X64 安装对应的
安装. Net 4.0 或者. Net 4.0 Client Profile
必有的依赖项(CEF code)
(UnicodeSupportdata)
,,
,
根据不同的开发平台 ,, 至少有一个
5.2 依赖内容排错
重要说明: 不想看高 (dan) 达 (dan) 上 (teng) 分析的, 请直接看 5.3 依赖列表
因为我这是 nuget 引入的, debug/release 生成的内容很多, 直接运行也是成功的, 因此我以发布为例, 实际和 debug/release 下的调试是一样的.
首先发布好的内容是这样的
直接运行
会有很多报错, 因为 vs 的发布过程中忽略很多依赖内容, 下面介绍一下怎么一步步定位到缺少的依赖项:
运行生成的 exe, 会报错这个
遇到这个问题的肯定没好好看上边的内容, 从源码或者 debug/release 下找到 , 考到 exe 目录下这个错误就没有了
运行 exe 会有新的问题,
xxx 已停止工作 - 点击关闭程序
, 注意目录下出现了一个
, 打开显示
FATAL:v8_initializer.cc(155)] Failed to open V8 file 'D:\Project\2013\CefSharpDemo\CefSharpDemo \ 发布 \ Application Files\CefSharpDemo_1_0_0_7\natives_blob.bin' (reason: -4)
说明缺少
natives_blob.bin
, 同上边直接拷贝过来
继续运行 exe,form1 出现了但是没有内容, 这时候看 log 是没有新的报错的, 但是请持续观察, 报错需要等一会儿才会进来[1226/142128:WARNING:resource_bundle.cc(311)]locale_file_path.empty()forlocale
[1226/142128:ERROR:main_delegate.cc(724)]Couldnotload locale pakforen-US
[1226/142128:ERROR:main_delegate.cc(731)]Couldnotload
[1226/142128:ERROR:main_delegate.cc(748)]Couldnotload cef_100_percent.pak
[1226/142128:ERROR:main_delegate.cc(766)]Couldnotload cef_extensions.pak
根据报错加入
locales\ , ,cef_100_percent.pak,cef_extensions.pak
继续运行 exe,form1 出现了但是没有内容, 仔细研究日志[1226/142128:ERROR:child_process_launcher.cc(443)]Failedto launch child process
[1226/142129:ERROR:child_process_launcher.cc(443)]Failedto launch child process
[1226/142925:ERROR:child_process_launcher.cc(443)]Failedto launch child process
[1226/142926:ERROR:child_process_launcher.cc(443)]Failedto launch child process
[1226/143326:ERROR:child_process_launcher.cc(443)]Failedto launch child process
[1226/143327:ERROR:child_process_launcher.cc(443)]Failedto launch child process
[1226/143502:ERROR:child_process_launcher.cc(443)]Failedto launch child process
[1226/143503:ERROR:child_process_launcher.cc(443)]Failedto launch child process
看懂了吗, 没看懂?
好吧, 我也没看懂.... 只好把 debug/release 下的文件往这边粘贴然后试试, 然后在粘了
两个之后奇迹发生了.... 抓紧把之前粘的全删了...
现在已经正常了, 但是, 但是 log 里面还有报错[1226/145245:ERROR:gpu_child_thread.cc(260)]ExitingGPU process due to errors during initialization
[1226/145245:ERROR:browser_gpu_channel_host_factory.cc(133)]Failedto launch GPU process.
好了不废话了, 经过我的九牛二虎之力, 发现加入
,,d3dcompiler_43.dll,d3dcompiler_47.dll
就 OK 了
5.3 依赖文件列表
总结一下, CefSharp 必有的文件: ---locales||--
|--
|--cef_100_percent.pak
|--cef_extensions.pak
|--
|--
|--
|--
|--
|--d3dcompiler_43.dll
|--d3dcompiler_47.dll
|--
|--
|--
|--
|--natives_blob.bin
补充一下, 运行环境 vs2013,.NET4.0,Winfrom,CefSharp v40.0.1.
6, 总结
根据今天初步的部署, 测试, 感觉 CefSharp 可以算是比较成熟的 CEF 的在. net 下的实现了, JavaScript 和 C# 的交互做的简单易用, 感觉可以比较容易的将一个 Web 应用的资源经过一定的重新整合打造成为一个桌面程序.
吐槽: 一个字大, 因为从根本上是集成了一个 chrome 浏览器, 所以以上简单的 Demo 的发布程序的 x64,release 版本就达到了 99.5M,360 压缩, 7z 格式压缩后 30.6m, 正式项目增加了代码, 引入了其他的 dll, 资源文件等会更大; 不知道有没有方法可以做精简
以上均为个人看法, 各路大神请指点
来源: