cefsharp已停止工作_Winform下CefSharp的引用、配置、实例与报错排除(源码)

时间:2025-03-28 17:30:24

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, 资源文件等会更大; 不知道有没有方法可以做精简

以上均为个人看法, 各路大神请指点

来源: