Skip to content

CefSharp中文帮助文档

supperlitt edited this page Jun 6, 2016 · 21 revisions

目录

1、基础知识

1.1 cefsharp设置默认语言

1.2 cefSharp 服务器运行要求

1.3 cefsharp设置网页接受语言AcceptLanguage

1.4 cef设置userAgent

2、配置管理

2.1、CommandLine配置

3、请求流程处理

3.1 读取网页源代码

3.2 获取页面中的指定文件内容(.jpg,.js等)

3.3 过滤某些页面内容,例如图片或某些文字

4、 Cookie处理

4.1 设置cookie

4.2 读取cookie

5、 Js处理

5.1 基本的同步js操作

5.2 其他Frame操作

6、 资源清理

6.1 浏览器本身处理

6.2 需要关闭浏览器负载程序时操作

7、 扩展功能

8、 常见错误

8.1 下载CefSharp master zip code文件编译报错

8.2 无法创建新的堆栈防护页面

9、 GitHub---Wiki(部分内容使用了Google进行翻译)

9.1.你如何处理从.NET中的JavaScript方法?

9.2.如何调用Javascript方法返回的结果呢?

9.3.你如何暴露的.NET类为Javascript?

9.4.为什么我得到一个错误有关“无法加载文件或程序集CefSharp.Core.dll”或它的一个依赖。指定的模块找不到。“当试图运行基于我CefSharp的应用程序?它编译成功,但不运行?它运行我的开发机器上,虽然抛出一个异常,当我把它复制到另一台计算机?

9.5.为什么在Visual Studio WPF设计不是当我添加一个ChromiumWebBrowser我的应用程序工作?

9.6.我如何包括在目标应用程序的Visual Studio的C ++ 2012/2013再发行?

9.7.我如何重写的Javascript window.alert行动和相似?

9.8.在哪里CefSharp3二进制文件?

9.9.Windows XP / 2003支持

9.10.哪些文件,我需要包括,当我重新发布使用CefSharp的应用程序?

9.11.构建过程中不能复制CEF文件

9.12.为什么IndexedDB的返回QuotaExceededError?

9.13.你是如何处理在C#中Javascript事件?

10、 参考网址

11、 其他

1、基础知识

1.1 cefsharp设置默认语言

cefsharp是不错的浏览器内核封装版本之一,默认语言是en-US,这个一直困扰着项目,项目好多处需修改,后来经多次尝试,才发现,原来设置默认语言这么简单。 Loacal 属性就是对CefSharp运行语言环境进行设置 var setting = new CefSharp.CefSettings();

// 设置语言 setting.Locale = "zh-CN"; CefSharp.Cef.Initialize(setting, true, false); 以上这段代码一定要在new ChromiumWebBrowser之前调用

1.2 cefSharp 服务器运行要求

.net framework 环境和 vc++ 2013 runtime (x86/x64)

1.3 cefsharp设置网页接受语言AcceptLanguage

什么是 cefsharp设置网页接受语言AcceptLanguage 1.设置浏览器的请求控制器  webView.RequestHandler = new RequestHandler();  2.新建RequestHandler类继承IRequestHandler接口,实现方法OnBeforeResourceLoad public bool OnBeforeResourceLoad(IWebBrowser browser, IRequestResponse requestResponse) { IDictionary<string, string> headers = requestResponse.Request.GetHeaders(); headers.Add("Accept-Language", "zh,zh-cn,zh-tw"); requestResponse.Request.SetHeaders(headers); return false; }

1.4 cef设置userAgent

var setting = new CefSharp.CefSettings(); setting.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"; CefSharp.Cef.Initialize(setting, true, false);

2、配置管理

2.1、CommandLine配置

所有配置:http://www.ericdlarson.com/misc/chrome_command_line_flags.html 样例参考: var settings = new CefSettings(); settings.CefCommandLineArgs.Add("no-proxy-server", "1"); settings.CefCommandLineArgs.Add("proxy-server", "ProxyAddress"); Cef.Initialize(settings, true, true);

3、请求流程处理

3.1 读取网页源代码

在页面加载完成后处理, 依赖最低环境 4.5.2 async void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e) { Log.WriteLog("browser_FrameLoadEnd:" + e.Url);

var result = await browser.GetSourceAsync();

}

如果想在4.0下环境操作需要使用。  var task = browser.GetSourceAsync(); task.Wait(); string content = task.Result;

3.2 获取页面中的指定文件内容(.jpg,.js等)

A.首先需要对ChromiumWebBrowser 的 IRequestHandler RequestHandler进行实现。 B.需要对 IRequestHandler 的IResponseFilter IRequestHandler.GetResourceResponseFilter 方法进行重写。 C.需要写一个类实现 IResponseFilter 接口。 D.然后就可用在IResponseFilter 的 FilterStatus Filter(Stream dataIn, out long dataInRead, Stream dataOut, out long dataOutWritten) 方法中,读取指定内容的流了。

3.3 过滤某些页面内容,例如图片或某些文字

具体实现,参考 3.2 ,在最后的Filter方法中,对返回的dataOut不进行赋值或者,取到值,然后replace处理,返回其他数据,即可。

4、Cookie处理

4.1 设置cookie

var cookieManager = CefSharp.Cef.GetGlobalCookieManager(); await cookieManager.SetCookieAsync("http://" + domain, new CefSharp.Cookie( { Domain = domain, Name = name, Value = value, Expires = DateTime.MinValue });

4.2 读取cookie

建立Cookie读取对象,继承接口 ICookieVisitor public class CookieVisitor : CefSharp.ICookieVisitor { public event Action<CefSharp.Cookie> SendCookie; public bool Visit(CefSharp.Cookie cookie, int count, int total, ref bool deleteCookie) { deleteCookie = false; if (SendCookie != null) { SendCookie(cookie); }

        return true;
    }
}

在browser事件中进行处理 private void browser_FrameLoadEnd(object sender, CefSharp.FrameLoadEndEventArgs e) { var cookieManager = CefSharp.Cef.GetGlobalCookieManager();

CookieVisitor visitor = new CookieVisitor();
visitor.SendCookie += visitor_SendCookie;
cookieManager.VisitAllCookies(visitor);

}

/// 回调事件 private void visitor_SendCookie(CefSharp.Cookie obj) { cookies += obj.Domain.TrimStart('.') + "^" + obj.Name + "^" + obj.Value + "$"; }

5、Js处理

5.1 基本的同步js操作

browser.GetBrowser().MainFrame.ExecuteJavaScriptAsync("document.getElementById('testid').click();"); browser.GetBrowser().MainFrame.ExecuteJavaScriptAsync("document.getElementById('testid2').value='123'");

5.2 其他Frame操作

string script = "if(document.getElementById('img_out_10000')){ document.getElementById('img_out_10000').click(); }"; var list = browser.GetBrowser().GetFrameNames(); if (list.Count > 1) { browser.GetBrowser().GetFrame(list[1]).ExecuteJavaScriptAsync(script); }

5.3 js回调,C#方法

参见本文档:9.3

6、资源清理

6.1 浏览器本身处理

static ChromiumWebBrowser() { if (CefSharpSettings.ShutdownOnExit) { Application.ApplicationExit += OnApplicationExit; } }

private static void OnApplicationExit(object sender, EventArgs e) { Cef.Shutdown(); }

6.2 需要关闭浏览器负载程序时操作

try { browser.CloseDevTools(); browser.GetBrowser().CloseBrowser(true); } catch { }

        try
        {
            if (browser != null)
            {
                browser.Dispose();
                Cef.Shutdown();
            }
        }
        catch { }

7、扩展功能

8、常见错误

8.1 下载CefSharp master zip code文件编译报错

下载地址:https://codeload.github.com/cefsharp/CefSharp/zip/master 错误提示:

由于编译路径存在中文导致。

8.2 无法创建新的堆栈防护页面

可能是由于 进程“ CefSharp.BrowserSubprocess.exe ”没有正常结束掉,一直占用内存增加,直到...

9、GitHub---Wiki(部分内容使用了Google进行翻译)

快速TOC常见问题解答 本FAQ〜10个项目。它试图展示一些很酷的CefSharp功能和一些最常见的问题的的。 更多的提示看打成FAQ-能的问题越来越多! 1.你如何称呼从.NET JavaScript方法? 2.如何调用Javascript方法返回的结果呢? 3.你如何暴露的.NET类为Javascript? 4.“无法加载文件或程序集CefSharp.Core.dll”或它的一个依赖。 5.为什么在Visual Studio WPF设计不是当我添加一个ChromiumWebBrowser我的应用程序工作? 6.我如何包括在目标应用程序的Visual Studio的C ++ 2012/2013再发行? 7.我如何重写的Javascript window.alert行动和相似? 8.在哪里CefSharp3二进制文件? 9.Windows XP / 2003支持? 10.哪些文件,我需要包括,当我重新发布使用CefSharp的应用程序? 11.构建过程中不能复制CEF文件 12.为什么IndexedDB的返回QuotaExceededError? 13.你是如何处理在C#中Javascript事件?

1.你如何处理从.NET中的JavaScript方法?

简单的代码可能是这个样子: var script = string.Format("document.body.style.background = '{0}'", colors[color_index++]);if (color_index >= colors.Length) { color_index = 0; }

browser.GetMainFrame().ExecuteJavaScriptAsync(script);

不幸的是加载DOM之前OnFrameLoadStart被调用,所以你需要使用如下之一:FrameLoadEnd / LoadingStateChanged / IRenderProcessMessageHandler.OnContextCreated。下面是几个例子

browser.RenderProcessMessageHandler = new RenderProcessMessageHandler(); public class RenderProcessMessageHandler : IRenderProcessMessageHandler { // Wait for the underlying Javascript Context to be created, this is only called for the main frame. // If the page has no javascript, no context will be created. void IRenderProcessMessageHandler.OnContextCreated(IWebBrowser browserControl, IBrowser browser, IFrame frame) { const string script = "document.addEventListener('DOMContentLoaded', function(){ alert('DomLoaded'); });";

frame.ExecuteJavaScriptAsync(script);

} } //Wait for the page to finish loading (all resources will have been loaded, rendering is likely still happening) browser.LoadingStateChanged += (sender, args) => { //Wait for the Page to finish loading if (args.IsLoading == false) { browser.ExecuteJavaScriptAsync("alert('All Resources Have Loaded');"); } } //Wait for the MainFrame to finish loading browser.FrameLoadEnd += (sender, args) => { //Wait for the MainFrame to finish loading if(args.Frame.IsMain) { args.Frame.ExecuteJavaScriptAsync("alert('MainFrame finished loading');"); } };

注意:脚本是在Frame级别执行,永远页具有至少一个帧(MainFrame)。该IWebBrowser.ExecuteScriptAsync扩展方法是为了向下兼容,你可以使用它作为一个快捷方式到主框架上执行JS。

2.如何调用Javascript方法返回的结果呢?

如果您需要评估代码,返回一个值,使用Task EvaluateScriptAsync(string script, TimeSpan? timeout)方法。 JavaScript代码是异步执行的,因此使用.NET Task类返回一个响应,其中包含错误消息,结果和一个成功(布尔)标志。 // Get Document Height var task = frame.EvaluateScriptAsync("(function() { var body = document.body, html = document.documentElement; return Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight ); })();", null);

task.ContinueWith(t => { if (!t.IsFaulted) { var response = t.Result; EvaluateJavaScriptResult = response.Success ? (response.Result ?? "null") : response.Message; } }, TaskScheduler.FromCurrentSynchronizationContext()); 有关更详细的例子看看这个要点 脚本是在帧级别执行,永远页至少有一个Frame(MainFrame) 只有微不足道的值可以返回(如int,布尔,字符串等) - 而不是一个复杂的(用户定义的)类型,你自己已经定义。这是因为没有(易)的方式来揭露一个随机的Javascript对象到.NET世界,至少不是今天。然而,一个可行的方法是把你想返回到你的.NET代码到一个JSON字符串使用JavaScript JSON.toStringify()方法,而该字符串返回到你的.NET代码的JavaScript对象。然后,你可以解码该字符串与类似JSON.net .NET对象。看到这个MSDN链接了解更多信息。 (https://msdn.microsoft.com/en-us/library/ie/cc836459(v=vs.94).aspx)

3.你如何暴露的.NET类为Javascript?

像这样: public class BoundObject { public string MyProperty { get; set; } public void MyMethod() { // Do something really cool here. } } // ... // After your ChromiumWebBrowser has been created browser.RegisterJsObject("bound", new BoundObject()); In the actual JS code, you would use the object like this: bound.myProperty; // use this syntax to access the property bound.myMethod(); // use this to call the method.

请注意:

默认情况下的方法和属性就变成驼峰,即第一个字母是小写,使其使用更与你的JavaScript代码的其余部分一起顺利。对于39.0.1和更高,这是可选的,可以使用camelCaseJavascriptNames布尔参数指定此行为 RegisterJsObject应该直接叫你创建ChromiumWebBrowser的实例后。内部CEF浏览器实例已初