CefSharp中文幫助文檔javascript
目錄css
基礎知識html
1.1 cefsharp設置默認語言java
1.2 cefSharp 服務器運行要求c++
1.3 cefsharp設置網頁接受語言AcceptLanguagegit
1.4 cef設置userAgentgithub
二、配置管理web
2.一、CommandLine配置redis
三、請求流程處理瀏覽器
3.1 讀取網頁源代碼
3.2 獲取頁面中的指定文件內容(.jpg,.js等)
3.3 過濾某些頁面內容,例如圖片或某些文字
3.4 文件進一步獲取,獲取完整內容
3.5 文件進一步獲取,獲取完整內容(優化,Content-Length不一致)
四、Cookie處理
4.1 設置cookie
4.2 讀取cookie
五、Js處理
5.1 基本的同(異)步js操做
5.2 其餘Frame操做
5.3 js回調,C#方法
六、資源清理
6.1 瀏覽器自己處理
6.2 須要關閉瀏覽器負載程序時操做
七、擴展功能
八、常見錯誤
8.1 下載CefSharp master zip code文件編譯報錯
8.2 沒法建立新的堆棧防禦頁面
8.3 結束瀏覽器後,CefSharp.BrowserSubprocess.exe進行沒法結束
九、GitHub---Wiki(部份內容使用了Google進行翻譯)
快速FAQ TOC 英文版本
1. 如何使用.NET 調用 JavaScript方法?
2. 如何獲取 Javascript 方法返回的結果?
3. 如何暴露.NET類,提供給Javascript?
4. 爲何我獲得一個錯誤有關「沒法加載文件或程序集 CefSharp.Core.dll」或它的一個依賴。指定的模塊找不到。「當試圖運行基於我CefSharp的應用程序?它編譯成功,但不運行?它運行個人開發機器上,雖然拋出一個異常,當我把它複製到另外一臺計算機?
5. 爲何當我將 ChromiumWebBrowser 添加到個人應用程序時,Visual Studio WPF設計器不起做用?
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事件?
14. 如何實現 WinForms 拖放?
十、參考網址
十一、其餘
基礎知識
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以前調用
-
public App()
-
{
-
//Monitor parent process exit and close subprocesses if parent process exits first
-
//This will at some point in the future becomes the default
-
CefSharpSettings.SubprocessExitIfParentProcessClosed = true;
-
-
var settings = new CefSettings()
-
{
-
AcceptLanguageList = "zh-CN",
-
//By default CefSharp will use an in-memory cache, you need to specify a Cache Folder to persist data
-
CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache")
-
};
-
-
//Example of setting a command line argument
-
//Enables WebRTC
-
settings.CefCommandLineArgs.Add( "enable-media-stream", "1");
-
-
//Perform dependency check to make sure all relevant resources are in our output directory.
-
Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);
-
}
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.一、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.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());
-
}
-
}
-
}
四、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 + "$";
-
}
五、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.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 { }
七、擴展功能
八、常見錯誤
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方法。
九、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?
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
十、參考網址
http://www.cnblogs.com/TianFang/p/4658151.html