-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
CefSharp中文帮助文档
9.4.为什么我得到一个错误有关“无法加载文件或程序集CefSharp.Core.dll”或它的一个依赖。指定的模块找不到。“当试图运行基于我CefSharp的应用程序?它编译成功,但不运行?它运行我的开发机器上,虽然抛出一个异常,当我把它复制到另一台计算机?
cefsharp是不错的浏览器内核封装版本之一,默认语言是en-US,这个一直困扰着项目,项目好多处需修改,后来经多次尝试,才发现,原来设置默认语言这么简单。 Loacal 属性就是对CefSharp运行语言环境进行设置 var setting = new CefSharp.CefSettings();
// 设置语言 setting.Locale = "zh-CN"; CefSharp.Cef.Initialize(setting, true, false); 以上这段代码一定要在new ChromiumWebBrowser之前调用
.net framework 环境和 vc++ 2013 runtime (x86/x64)
什么是 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; }
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);
所有配置: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);
在页面加载完成后处理, 依赖最低环境 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;
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.2 ,在最后的Filter方法中,对返回的dataOut不进行赋值或者,取到值,然后replace处理,返回其他数据,即可。
var cookieManager = CefSharp.Cef.GetGlobalCookieManager(); await cookieManager.SetCookieAsync("http://" + domain, new CefSharp.Cookie( { Domain = domain, Name = name, Value = value, Expires = DateTime.MinValue });
建立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 + "$"; }
browser.GetBrowser().MainFrame.ExecuteJavaScriptAsync("document.getElementById('testid').click();"); browser.GetBrowser().MainFrame.ExecuteJavaScriptAsync("document.getElementById('testid2').value='123'");
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); }
参见本文档:9.3
static ChromiumWebBrowser() { if (CefSharpSettings.ShutdownOnExit) { Application.ApplicationExit += OnApplicationExit; } }
private static void OnApplicationExit(object sender, EventArgs e) { Cef.Shutdown(); }
try { browser.CloseDevTools(); browser.GetBrowser().CloseBrowser(true); } catch { }
try
{
if (browser != null)
{
browser.Dispose();
Cef.Shutdown();
}
}
catch { }
下载地址:https://codeload.github.com/cefsharp/CefSharp/zip/master 错误提示:
由于编译路径存在中文导致。
可能是由于 进程“ CefSharp.BrowserSubprocess.exe ”没有正常结束掉,一直占用内存增加,直到...
快速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事件?
简单的代码可能是这个样子: 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。
如果您需要评估代码,返回一个值,使用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)
像这样: 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浏览器实例已初