标签:1.2 bin 发布 空间名 复制 模型 javascrip control 菜单
Winform下CefSharp的引用、配置、实例与报错排除
本文详细介绍了CefSharp在vs2013、.net4.0环境下,创建Winfrom项目、引用CefSharp的方法,演示了winfrom下CefSharp的基本使用,包括显示网页url/本地html显示、JavaScript调用异步C#方法、JavaScript调用带参数C#方法、JavaScript调用委托C#方法、JavaScript调用C#返回实体对象、ChromiumWebBrowser控件扩展IContextMenuHandler接口实现禁用右击按钮菜单、简单介绍WebGL页面渲染;详细介绍了的CefSharp依赖项、常见报错查看与必要依赖项分析,最后进行了简单总结、并提供了源码的下载.
[TOC]
装一手,比较简单的英语
CefSharp lets you embed Chromium in .NET apps. It is a lightweight .NET wrapper around the Chromium Embedded Framework (CEF) by Marshall A. Greenblatt. About 30% of the bindings are written in C++/CLI with the majority of code here is C#. It can be used from C# or VB, or any other CLR language. CefSharp provides both WPF and WinForms web browser control implementations.
CefSharp is BSD licensed, so it can be used in both proprietary and free/open source applications. For the full details, see the LICENSE file.
自己总结的:
CefShar是一个提供了Chromium Embedded Framework (CEF)的.NET接口的开源项目,提供了Winform、WPF封装,可以用来代替微软的WebBrowser,浏览网页,尤为强大的是实现了C#、VB等vs支持的语言与JavaScript的交互方法。
我的开发环境vs2013、.net4.0,Nugget中搜索CefSharp显示的版本是v53,然而v51.0.0-pre01
的Breaking Changes里面有这么一句
CefSharp requires at least .Net 4.5.2 (Last version to support .Net 4.0 is 49)
不想安装.net4.5.2,所以只能通过工具-程序包管理器-程序包管理控制台
手动命令行导入版本v49。0.1的,输入命令Install-Package CefSharp.WinForms -Version 49.0.1
回车等待执行完成,我这里已经安装过了。
其他版本命令请参考http://www.nuget.org/packages/CefSharp.WinForms.
等待导入成功,生成一下...报错...
CefSharp.Common does not work correctly on ‘AnyCPU‘ platform. You need to specify platform (x86 / x64).
嗯?!!!
cefsharp不支持anycup,还需要设置一下目标平台为x86或x64
如果你以为只是在项目名右击-属性-生成-目标平台
改为x86就太天真了....
反正我试了不行...
正确的姿zhi势shi: 解决方案名右击-属性-配置属性-配置
,右边平台选择x86或x64,什么?选不到?
点击当前界面右上角配置管理器-活动解决方案平台
下拉新建
,x86/x64随便选,回来这边下拉已经可以选择了,完事左下角确定,再生成一下试试吧
以上看不懂的参考这里.net使用cefsharp开源库开发chrome浏览器(二)
对照下面在一个Form的对应位置添加代码
using CefSharp.WinForms;
public partial class Form1 : Form
{
ChromiumWebBrowser webBrower = null;
public Form1()
{
InitializeComponent();
Load += Form_Load;
}
private void Form_Load(object sender, EventArgs e)
{
string path = "www.baidu.com";
webBrower = new ChromiumWebBrowser(path);
webBrower.Dock = DockStyle.Fill;//填充方式
this.Controls.Add(webBrower);
}
}
直接运行就OK了
把path改为File协议就行,例如:显示程序下的文件夹html中的test.html
//获取文件的物理路径
string path = AppDomain.CurrentDomain.BaseDirectory + "\\html\\test.html";
//转换为File协议路径
path = "file://" + path.Replace("\\", "/");
如果实在不知道怎么写的话,建议直接用浏览器把html打开,地址栏里面显示的file://链接就是File协议路径
需要在 test.html文件上
右击-属性-复制到输出目录
改为始终复制
,这样调试时debug下面才会有这个文件
推荐个CCS3动画的html,直接右击保存到本地就行了大风车CCS3动画,修改完成,同样运行就可以看到页面了,运行还是挺流畅的.
走弯路后的说明:BoundObject等这三个类以及里面的方法都是可以自己任意定义实现的,和普通的方法类没有太大区别,没有必要去源码中拷过来.
从源码的CefSharp.Example
中找到三个类BoundObject、SubBoundObject、ExceptionTestBoundObject的源码拷过来,记得对应着自己的项目把命名空间名改了。
如果是.net4.0,TestCallback、TestCallbackException两个方法有提示async/await、Task.Run的报错,处理方式:
Install-Package Microsoft.Bcl.Async
.如果和我一样提示Nuget版本2.7太低、至少需要2.8的,需要卸载升级Nuget,步骤:
VS-〉打开菜单“工具”-“扩展管理器”-〉选择“NuGet Package Manager”-〉点击“卸载”
,然后会提示重启,不自动重启的话可以自己手动重启我这里选择不升级.net 4.5后面一种方法,同时安装Microsoft.Bcl.Async.
这里实现的是一个延时回调的例子,即点一个按钮,调用绑定的C#方法在3秒后显示一条消息同时调用js方法立即显示一条消息。
测试内容准备:
BoundObject中定义回调方法(可以自己定义一个空的BoundObject类,增加一下内容)
public void TestCallback(IJavascriptCallback javascriptCallback)
{
//.net 4.0 的写法
const int taskDelay = 3000;
Task.Factory.StartNew(async () =>
{
Delay(taskDelay);
using (javascriptCallback)
{
//var response = new CallbackResponseStruct("This callback from C# was delayed " + taskDelay + "ms");
await javascriptCallback.ExecuteAsync(" 来自C#的返回值,在当前延迟" + taskDelay + "ms");
}
});
/*
//.net 4.5的写法
const int taskDelay = 1500;
Task.Run(async () =>
{
await Task.Delay(taskDelay);
using (javascriptCallback)
{
//NOTE: Classes are not supported, simple structs are
var response = new CallbackResponseStruct("This callback from C# was delayed " + taskDelay + "ms");
await javascriptCallback.ExecuteAsync(response);
}
});
*/
}
新建个html,body中录入一下内容
<p> Javascript Callback Test </p>
<script type="text/javascript">
function callback(s) {
var result = document.getElementById(‘show‘);
result.innerText += "callback返回值:" + s.toString() + " 时间:" + Date();
}
function TestCallback() {
//调用后台C#方法TestCallback,返回结果回调方法callback
bound.TestCallback(callback);
var result = document.getElementById(‘show‘);
result.innerText = "方法返回 时间: " + Date() + "\n";
//window.location.assign("http://www.baidu.com");
}
</script>
<button onclick="TestCallback()">TestCallBakck</button>
<br />
<span id="show"></span>
可以运行一下了,点击一下TestCallBakck
按钮,会首先显示一行内容与时间,3秒后显示第二行内容.
准备内容:
BoundObject添加Repeat方法
public string Repeat(string str, int n)
{
string result = String.Empty;
for (int i = 0; i < n; i++)
{
result += str;
}
return result;
}
html内容
<p>带参数调用C# repeat方法</p>
<span id="content"></span>
<script type="text/javascript">
var result = bound.Repeat("hello ", 6);
document.getElementById("content").innerHTML = ""+result+"";
</script>
执行结果
这里将一个方法ReturnJsonEmployeeList作为参数进行传递,并返回一个json数据进行解析展示
BoundObject中添加方法
public string ReturnJsonEmployeeList()
{
return "{\"employees\":[{\"firstName\":\"John\", \"lastName\":\"Doe\"},{\"firstName\":\"Anna\", \"lastName\":\"Smith\"},{\"firstName\":\"Peter\", \"lastName\":\"Jones\"}]}";
}
html内容
<p> 委托C#方法-返回json字符串</p>
<script type="text/javascript">
function myfunc(fucPara) {
return fucPara();
}
var res = myfunc(bound.ReturnJsonEmployeeList);
document.write("委托输出结果:" + res + "<br>");
var json = JSON.parse(res); //eval("‘"+ res+"‘");
document.write("employees 数量:" + json.employees.length + "<br>");
document.write("json.employees[0].lastName :" + json.employees[0].lastName);
</script>
运行结果:
新建类SubBoundObject,对照添加以下内容
public class SubBoundObject
{
public string SimpleProperty { get; set; }
public SubBoundObject()
{
SimpleProperty = "This is a very simple property.";
}
public string GetMyType()
{
return "My Type is " + GetType();
}
public string EchoSimpleProperty()
{
return SimpleProperty;
}
}
BoundObject中添加内容
public SubBoundObject SubObject { get; set; }
public SubBoundObject GetSubObject()
{
return SubObject;
}
html中添加内容
<p>返回实体对象</p>
<script type="text/javascript">
document.write("bound.GetSubObject().SimpleProperty : " + bound.GetSubObject().SimpleProperty);
</script>
运行结果:
禁用右击菜单需要创建一个类实现接口IContextMenuHandler,然后把这个类赋值给ChromiumWebBrowser的MenuHandler即可。这里创建类MenuHandler:
internal class MenuHandler : IContextMenuHandler
{
public void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model)
{
model.Clear();
}
public bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags)
{
return false;
}
public void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame)
{
}
public bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback)
{
return false;
}
}
配置到ChromiumWebBrowser:
webBrower.MenuHandler = new Class.MenuHandler();
这里只是禁用了菜单,也可以在相关事件里面增加内容,实现自定义右击菜单、不同页面的不同右击菜单.
WebGL(全写Web Graphics Library)是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等。
使用WebGL可以实现很炫的页面效果,以下这些实例都可以直接应用到一个引入了CefSharp的WinFrom桌面程序上面.
9个令人震惊的WebGL示例
20个使用WebGL和Three.js实现的网页场景
CefSharp官方文件readme.txt中有以下要求:
重要说明:不想看高(dan)达(dan)上(teng)分析的,请直接看5.3依赖列表
因为我这是nuget引入的,debug/release生成的内容很多,直接运行也是成功的,因此我以发布为例,实际和debug/release下的调试是一样的。
首先发布好的内容是这样的
直接运行setup.exe
会有很多报错,因为vs的发布过程中忽略很多依赖内容,下面介绍一下怎么一步步定位到缺少的依赖项:
xxx已停止工作-点击关闭程序
,注意目录下出现了一个debug.log
,打开显示说明缺少natives_blob.bin
,同上边直接拷贝过来
locales\en-US.pak 、 cef.pak、cef_100_percent.pak、cef_extensions.pak
CefSharp.BrowserSubprocess.Core.dll CefSharp.BrowserSubprocess.exe
两个之后奇迹发生了....抓紧把之前粘的全删了...现在已经正常了,但是、但是log里面还有报错
[1226/145245:ERROR:gpu_child_thread.cc(260)] Exiting GPU process due to errors during initialization
[1226/145245:ERROR:browser_gpu_channel_host_factory.cc(133)] Failed to launch GPU process.
好了不废话了,经过我的九牛二虎之力,发现加入libEGL.dll、libGLESv2.dll、d3dcompiler_43.dll、d3dcompiler_47.dll
就OK了
总结一下,CefSharp必有的文件:
---locales
| |--en-US.pak
|--cef.pak
|--cef_100_percent.pak
|--cef_extensions.pak
|--CefSharp.BrowserSubprocess.Core.dll
|--CefSharp.BrowserSubprocess.exe
|--CefSharp.Core.dll
|--CefSharp.dll
|--CefSharp.WinForms.dll
|--d3dcompiler_43.dll
|--d3dcompiler_47.dll
|--icudtl.dat
|--libcef.dll
|--libEGL.dll
|--libGLESv2.dll
|--natives_blob.bin
补充一下,运行环境vs2013、.NET4.0,Winfrom,CefSharp v40.0.1.
根据今天初步的部署、测试,感觉CefSharp可以算是比较成熟的CEF的在.net下的实现了,JavaScript和C#的交互做的简单易用,感觉可以比较容易的将一个Web应用的资源经过一定的重新整合打造成为一个桌面程序.
吐槽:一个字大,因为从根本上是集成了一个chrome浏览器,所以以上简单的Demo的发布程序的x64、release版本就达到了99.5M,360压缩、7z格式压缩后30.6m,正式项目增加了代码、引入了其他的dll、资源文件等会更大;不知道有没有方法可以做精简
以上均为个人看法,各路大神请指点
CefSharpDemo20161227 包含packages 157M
CefSharpDemo20161227 不含packages 131K
下载请去原文:http://huisky.com/blog/16122515111968
标签:1.2 bin 发布 空间名 复制 模型 javascrip control 菜单
原文地址:http://www.cnblogs.com/Leo_wl/p/6239233.html