目錄
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 過濾某些頁面內容,例如圖片或某些文字
3.4 文件進一步獲取,獲取完整內容
3.5 文件進一步獲取,獲取完整內容(優化,Content-Length不一致)
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 無法創建新的堆棧防護頁面
8.3 結束瀏覽器后,CefSharp.BrowserSubprocess.exe進行無法結束
9、 GitHub---Wiki(部分內容使用了Google進行翻譯)
9.1 如何使用.NET 調用 JavaScript方法?
9.2 如何獲取 Javascript 方法返回的結果?
9.3 如何暴露.NET類,提供給Javascript?
9.4 為什么我得到一個錯誤有關“無法加載文件或程序集 CefSharp.Core.dll
”或它的一個依賴。指定的模塊找不到。“當試圖運行基於我CefSharp的應用程序?它編譯成功,但不運行?它運行我的開發機器上,雖然拋出一個異常,當我把它復制到另一台計算機?
9.5 為什么當我將 ChromiumWebBrowser 添加到我的應用程序時,Visual Studio WPF設計器不起作用?
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事件?
9.14 如何實現 WinForms 拖放?
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://peter.sh/experiments/chromium-command-line-switches/
樣例參考:
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處理,返回其他數據,即可。
3.4 文件進一步獲取,獲取完整內容
說明:由於很多文件無法獲取到完整內容,再者具體文件內容在Filter里面進行了控制,而Fileter的內容依賴於IRequestHandler所以,外部只能操作Handler得到數據。 所以需要在,Filter和Hanlder類中,使用事件來傳遞具體的內容。代碼如下。 Filter類如下:
public class TestImageFilter : IResponseFilter { public event Action<byte[]> NotifyData; private int contentLength = 0; private List<byte> dataAll = new List<byte>(); public void SetContentLength(int contentLength) { this.contentLength = contentLength; } public FilterStatus Filter(System.IO.Stream dataIn, out long dataInRead, System.IO.Stream dataOut, out long dataOutWritten) { try { if (dataIn == null) { dataInRead = 0; dataOutWritten = 0; return FilterStatus.Done; } dataInRead = dataIn.Length; dataOutWritten = Math.Min(dataInRead, dataOut.Length); dataIn.CopyTo(dataOut); dataIn.Seek(0, SeekOrigin.Begin); byte[] bs = new byte[dataIn.Length]; dataIn.Read(bs, 0, bs.Length); dataAll.AddRange(bs); if (dataAll.Count == this.contentLength) { // 通過這里進行通知 NotifyData(dataAll.ToArray()); return FilterStatus.Done; } else if (dataAll.Count < this.contentLength) { dataInRead = dataIn.Length; dataOutWritten = dataIn.Length; return FilterStatus.NeedMoreData; } else { return FilterStatus.Error; } } catch (Exception ex) { dataInRead = dataIn.Length; dataOutWritten = dataIn.Length; return FilterStatus.Done; } } public bool InitFilter() { return true; } }
Filter類有了,那我們如何知道數據流的具體長度呢?這就需要在Handler的實現的其他方法里面尋找了。
bool IRequestHandler.OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response) { //NOTE: You cannot modify the response, only the request // You can now access the headers //var headers = response.ResponseHeaders; try { var content_length = int.Parse(response.ResponseHeaders["Content-Length"]); if (this.filter != null) { this.filter.SetContentLength(content_length); } } catch { } return false; } private TestImageFilter filter = null; public event Action<byte[]> NotifyData; IResponseFilter IRequestHandler.GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response) { var url = new Uri(request.Url); if (url.AbsoluteUri.Contains("http://test.test.com/somehead?")) { this.filter = new TestImageFilter(); filter.NotifyData += filter_NotifyData; return filter; } return null; } void filter_NotifyData(byte[] data) { if (NotifyData != null) { NotifyData(data); } }
此方法為IRequestHandler的一部分實現,通過實現函數:IRequestHandler.GetResourceResponseFilter得到資源文件的長度,然后長度傳入Filter,在Filter中控制從而得到整個數據的真正長度。
3.5 文件進一步獲取,獲取完整內容(優化,Content-Length不一致)
由於,部分站點,返回數據是分片了的,即:不能通過,Content-Length的長度來判斷,程序的流是否完成。
所以需要其他方式處理,即:單個http請求完成的時候,會調用Complete方法,所以可以在這里處理。
下面是測試代碼: Filter管理類
public class FilterManager { private static Dictionary<string, IResponseFilter> dataList = new Dictionary<string, IResponseFilter>(); public static IResponseFilter CreateFilter(string guid) { lock (dataList) { var filter = new TestImageFilter(); dataList.Add(guid, filter); return filter; } } public static IResponseFilter GetFileter(string guid) { lock (dataList) { return dataList[guid]; } } }
TestFilter類,對流進行合並
public class TestImageFilter : IResponseFilter { public List<byte> dataAll = new List<byte>(); public FilterStatus Filter(System.IO.Stream dataIn, out long dataInRead, System.IO.Stream dataOut, out long dataOutWritten) { try { if (dataIn == null || dataIn.Length == 0) { dataInRead = 0; dataOutWritten = 0; return FilterStatus.Done; } dataInRead = dataIn.Length; dataOutWritten = Math.Min(dataInRead, dataOut.Length); dataIn.CopyTo(dataOut); dataIn.Seek(0, SeekOrigin.Begin); byte[] bs = new byte[dataIn.Length]; dataIn.Read(bs, 0, bs.Length); dataAll.AddRange(bs); dataInRead = dataIn.Length; dataOutWritten = dataIn.Length; return FilterStatus.NeedMoreData; } catch (Exception ex) { dataInRead = dataIn.Length; dataOutWritten = dataIn.Length; return FilterStatus.Done; } } public bool InitFilter() { return true; } }
最后是部分的。IRequestHandler實現代碼
public class RequestHandler : IRequestHandler { // 略去代碼 ... public event Action<byte[]> NotifyMsg; IResponseFilter IRequestHandler.GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response) { var url = new Uri(request.Url); if (url.AbsoluteUri.Contains("https://res.wx.qq.com/zh_CN/htmledition/v2/css/base/base2e4e03.css")) { var filter = FilterManager.CreateFilter(request.Identifier.ToString()); return filter; } return null; } void filter_NotifyData(byte[] data) { if (NotifyMsg != null) { NotifyMsg(data); } } void IRequestHandler.OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength) { if (request.Url.Contains("https://res.wx.qq.com/zh_CN/htmledition/v2/css/base/base2e4e03.css")) { var filter = FilterManager.GetFileter(request.Identifier.ToString()) as TestImageFilter; filter_NotifyData(filter.dataAll.ToArray()); } } }
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 ”沒有正常結束掉,一直占用內存增加,直到...
8.3 結束瀏覽器后,CefSharp.BrowserSubprocess.exe進行無法結束
需要確保,創建瀏覽器的線程和調用Cef.ShutDown();的線程確保在同一個線程中進行操作。 如果是主線程創建。關閉程序后BrowserSubprocess進程可以直接退出。 如果是非主線程,需要在創建瀏覽器,即:把瀏覽器綁定到控件的線程,調用shutdown方法。
9、GitHub---Wiki(部分內容使用了Google進行翻譯)
本文檔的大部分將被替換為新的 一般使用指南 - 必須閱讀!
快速FAQ TOC 英文版本
本FAQ〜10項。嘗試列出一些很酷的CefSharp特性和一些最常見的問題的的。
有關更多提示,請查看不斷增加的問題列表faq-able!
- 如何使用.NET 調用 JavaScript方法?
- 如何獲取 Javascript 方法返回的結果呢?
- 如何暴露.NET類,提供給Javascript?
- “無法加載文件或程序集
CefSharp.Core.dll
”或它的一個依賴。 - 為什么當我將 ChromiumWebBrowser 添加到我的應用程序時,Visual Studio WPF設計器不起作用?
- 如何在目標應用程序中包含Visual Studio C ++ 2012/2013可再發行組件?
- 如何重寫 Javascript 的
window.alert
事件和相似的? - CefSharp3二進制程序在哪里?
- Windows XP/2003支持?
- 當我重新發布使用CefSharp的應用程序時,需要包括什么文件?
- 構建過程不能復制CEF文件
- 為什么 IndexedDB 返回 QuotaExceededError?
- 在C#中如何處理Javascript事件?
- 如何實現 WinForms 拖放?
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);
什么時候可以開始執行 Javascript
?
不幸的是加載DOM之前OnFrameLoadStart被調用,所以你需要使用如下之一:FrameLoadEnd / LoadingStateChanged / IRenderProcessMessageHandler.OnContextCreated。下面是幾個例子
不幸的是,在加載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 級別執行,永遠頁面至少有一個Frame( MainFrame
)。 IWebBrowser.ExecuteScriptAsync
擴展方法是為了向后兼容,可以將其用作在主框架上執行 js
的快捷方式。
2. 如何獲取 Javascript 方法返回的結果?
如果需要評估返回值的代碼,使用 Task<JavascriptResponse> EvaluateScriptAsync(string script, TimeSpan? timeout)
方法。 JavaScript代碼是異步執行的,因此使用.NET Task
類返回一個響應,其中包含錯誤消息,結果和一個成功(bool)標志。
// 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());
有關更詳細的例子 Gist
Notes
- 腳本是在 Frame 級別執行,永遠頁面至少有一個Frame(
MainFrame
) - 只能返回一般的值(如int,bool,string等) - 不是您自己定義的復雜(用戶定義)類型。這是因為沒有(容易的)方式將隨機的JavaScript對象暴露給.NET World,至少不是今天。但是,一種可能的技術是,將要返回到.NET代碼的Javascript對象轉換為JSON對象,使用
JSON.toStringify()
方法轉化為JSON字符串,並將該字符串返回到您的.NET代碼。然后,您可以將該字符串解碼為一個類似JSON.net的.NET對象。有關更多信息,請參閱此MSDN鏈接。 (https://msdn.microsoft.com/library/cc836459(v=vs.94).aspx)
3. 如何暴露.NET類,提供給Javascript?
參考 般使用指南 - 如何公開.Net類
4. 為什么我得到一個錯誤有關“無法加載文件或程序集 CefSharp.Core.dll
”或它的一個依賴。指定的模塊找不到。“當試圖運行基於我CefSharp的應用程序?它編譯成功,但不運行?它運行我的開發機器上,雖然拋出一個異常,當我把它復制到另一台計算機?
這是一個常見的錯誤,通常是以下之一
- VC++ 2012/2013 可重新分發包*是為了在非開發者機器上運行CefSharp所必需的。有關詳細信息,請參閱下面的FAQ#6。 您可以將所需的dll作為應用程序的一部分。
- 執行文件夾中不存在所有依賴關系。
CefSharp
包括非托管
的dll和資源,這些文件通過安裝Nuget
包時包含在項目中的兩個.props
文件復制到執行文件夾。 請參閱下面所需的文件列表,確保所需的文件存在。 - 你通過安裝程序打包應用程序進行發布,並且不會在目標計算機上運行。 默認情況下,安裝程序不包括
非托管
資源,您需要手動添加它們。 對於ClickOnce
,請參閱#1314其他用戶提出的一些指針和解決方案。
可以在這里找到所需文件的列表:Output files description (Redistribution)
注: 如果在 XAML
中初始化 WPF
控件時遇到 FileNotFoundException
,這也適用。
注2:如果從源代碼編譯(不推薦使用 Nuget
包),並注意到您不能再以debug模式構建,但是release構建工作正常,您可能需要修復Visual Studio版本。 這種情況發生在少數情況下,您將獲得如上所示,丟失的非托管.dll文件相同的提示信息。
5. 為什么當我將 ChromiumWebBrowser 添加到我的應用程序時,Visual Studio WPF設計器不起作用?
注 版本 57.0.0
增加了最小的設計器支持,有關詳細信息,請參見 https://github.com/cefsharp/CefSharp/pull/1989。
舊版本不支持 WPF
設計器,這是不幸的,CefSharp是用C++代碼編寫的,后者又引用了CEF DLLs 導致的結果。這種情況下,Visual Studio 設計器不能夠很好的支持。在論壇的主題將進一步解釋,並提供可能的解決方法。 我認為(不幸的是)最簡單的解決方法是接受一個事實,即支持並不容易,但是還有其他方法,如果你真的覺得你需要舊版本。
6. 如何在目標應用程序中包含Visual Studio C ++ 2012/2013 再發布?
CefSharp
需要 VC ++運行時
。你必須安裝/包括這與你的應用程序的幾個選項:
- 你可以在你希望運行
CefSharp
基於應用程序的每台計算機上安裝VC++
。一旦安裝更新就可以通過Windows Update
進行管理。 - 您可以設置在
Visual Studio C++
再分發作為安裝程序的先決條件(即的ClickOnce或WiX的工具集) - 通過復制到您的項目在此文件夾(只有當你安裝了Visual Studio中的匹配版本存在)的內容:
#對於VC ++ 2012(86)
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\redist\x86\Microsoft.VC110.CRT
#對於VC ++ 2012(64)
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\redist\x64\Microsoft.VC110.CRT
#對於VC ++ 2013(86)
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\x86\Microsoft.VC120.CRT
#對於VC ++ 2013(64)
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\x64\Microsoft.VC120.CRT
隨着第三方法,你將不再需要為前提的 Visual C++ 2012/2013 運行時文件
安裝到客戶端。就目前的計划是留在VC2013官方CefSharp二進制版本。可行時,我們可能會切換到VC2015。如果你從源代碼構建自己的你部署的過程中必須與您構建環境。對於官方的 Nuget
版本的詳細信息請參見發布分支表。
欲了解更多信息,請參閱重新分發 Visual C++ 文件。要下載,請訪問Visual Studio C++ 2012/2013 再發行
一個新的選項是 JetBrains
在 Nuget.org
上有一個Microsoft.VC120.CRT.JetBrains ,似乎包含相關文件,您仍然需要連接一些后期構建任務將其復制到您的bin文件夾。
注意 當從源代碼構建時,確保在部署到沒有安裝 Visual Studio
的機器時以 Release
模式進行編譯。 Visual C++
使用一套不同的調試和發布版本的運行時庫。 Debug
運行時庫僅安裝有 Visual Studio
中。如果你使用他們已經建在釋放模式官方的 NuGet軟件包
,您可以隨后建立在調試模式下您的應用程序,因為只有在 Visual C++
項目需要在 Release
模式下進行編譯。
7. 如何重寫 Javascript 的 window.alert
事件和相似的事件?
ChromiumWebBrowser
控件提供了一個名為 JsDialogHandler
的屬性。 該屬性可以設置為一個類,可以用來覆蓋這些對話框的行為。
8. CefSharp3二進制程序在哪里?
CefSharp3被發布為 Nuget
包。 請參閱https://github.com/cefsharp/CefSharp/blob/master/README.md#nuget-packages 以獲取最新的穩定版本和預發行版本。
對於使用NuGet軟件包的一個非常簡單的示例項目,請參閱CefSharp.MinimalExample 存儲庫。 克隆它/下載源碼,如果你想要一個真正的小而簡單的例子,如何使用CefSharp3。
請注意: 平台目標
使用這些包時,必須 選擇 x86
或 x64
。 如果您選擇 AnyCPU
,NuGet magic將無法正常工作。_請參閱steps to configure your solution here。
9. Windows XP/2003支持?
我們不再支持 Windows XP/2003
。官方的 Nuget
軟件包沒有在 Windows XP/2003
上進行測試。 您可能會喜歡使用目標為 VC++ 2013
的較新版本( VC++ 2012 packages
有一個已知問題)。(記住 CefSharp.Example.*
項目是使用 .Net 4.5
編譯的,所以如果你想使用提供的例子,你必須重新定位它們並相應地更新代碼)。
請不要創建與 Windows XP
相關的 新的 問題。 以下 https://github.com/cefsharp/CefSharp/wiki/Windows-XP-No-Longer-Supported Wiki
頁面可能很有用,可以由任何具有 GitHub
帳戶的人進行編輯,因此請隨時提供,您認為可能證明有用的任何信息。
10. 當我重新發布使用CefSharp的應用程序時,需要包括什么文件?
請參閱: Output files description (Redistribution)
11. 構建過程不能復制CEF文件
有時,編譯過程不能復制CEF文件,並且會在最終失敗之前重試多次。 即使應用程序關閉,CefSharp.BrowserSubprocess.exe
仍然運行時也會發生這種情況。 解決方案,使用任務管理器,手動殺死 CefSharp.BrowserSubprocess.exe
。
12. 為什么 IndexedDB 返回 QuotaExceededError?
使用IndexedDB時,必須將CefSettings CachePath設置為當前用戶具有寫入權限的目錄。 在大多數情況下,您可以使用這樣的代碼創建緩存目錄,並在Initialize() 期間將設置傳遞給Cef:
// On Win7 this will create a directory in AppData. var cache = System.IO.Path.Combine(Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData), System.IO.Path.Combine("MyApplication","cache")); if (!System.IO.Directory.Exists (cache)) System.IO.Directory.CreateDirectory (cache); // Set the CachePath during initialization. var settings = new CefSettings(){CachePath = cache}; Cef.Initialize (settings);
13. 在C#中如何處理Javascript事件?
public class BoundObject { public void OnFrameLoadEnd (object sender, FrameLoadEndEventArgs e) { if(e.Frame.IsMain) { browser.ExecuteScriptAsync(@" document.body.onmouseup = function() { bound.onSelected(window.getSelection().toString()); } "); } } public void OnSelected(string selected) { MessageBox.Show("The user selected some text [" + selected + "]"); } } // ... // After your ChromiumWebBrowser has been instantiated (for WPF directly after `InitializeComponent();` in the control constructor). var obj = new BoundObject(); browser.RegisterJsObject("bound", obj); browser.FrameLoadEnd += obj.OnFrameLoadEnd ;
請注意:
- 在創建
ChromiumWebBrowser
實例之后,應該直接調用RegisterJsObject
"bound"
將作為可在網頁上運行的任何JS腳本訪問的頂級對象創建的對象的名稱。 您可以使用任何您喜歡的,但確保它不與現有的JS對象沖突,並且名稱與C#和JS匹配。- 此示例使用
FrameLoadEnd
事件即時將JS代碼注入到網頁中。 如果您控制了網頁,可以將JS代碼添加到網頁中。 - 我們使用單個字符串參數調用
OnSelected
C#方法。 您可以使用任何數量的參數,也可以不使用任何參數,但都必須是原始類型。 - 確保將復雜的JS對象轉換為字符串,或將其轉換為JSON。
- 由於CefSharp將通過其名稱搜索
OnSelected
方法,請確保您的混淆器不會將該方法重命名為別的東西,否則將不會被執行。
14. 如何實現 WinForms 拖放?
一個可能的解決方案概述 https://github.com/cefsharp/CefSharp/issues/1593#issuecomment-304451518
10、參考網址
http://www.cnblogs.com/TianFang/p/4658151.html
11、其他
轉自:https://github.com/cefsharp/CefSharp/wiki/CefSharp%E4%B8%AD%E6%96%87%E5%B8%AE%E5%8A%A9%E6%96%87%E6%A1%A3#a1_1