/// <summary> /// Manually call https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-destroywindow /// passing in the handle returned from <see cref="IBrowserHost.GetWindowHandle"/>. /// This method can be used to manually close the underlying CefBrowser instance. /// This will avoid the WM_Close message that CEF sends by default to the top level window. /// (Which closes your application). This method should generally only be used in the WinForms version. /// </summary> /// <param name="chromiumWebBrowser">the <see cref="ChromiumWebBrowser"/> or <see cref="ChromiumHostControl"/> instance.</param> /// <returns>If the function succeeds, the return value is true.</returns> /// <example> /// <code> /// //Invoke on the CEF UI Thread /// Cef.UIThreadTaskFactory.StartNew(() => /// { /// var closed = chromiumWebBrowser.DestroyWindow(); /// }); /// </code> /// </example> public static bool DestroyWindow(this IChromiumWebBrowserBase chromiumWebBrowser) { if (!Cef.CurrentlyOnThread(CefThreadIds.TID_UI)) { throw new InvalidOperationException("This method can only be called on the CEF UI thread." + "Use Cef.UIThreadTaskFactory to marshal your call onto the CEF UI Thread."); } if (chromiumWebBrowser.IsDisposed) { return(false); } var browser = chromiumWebBrowser.BrowserCore; if (browser == null) { return(false); } var handle = browser.GetHost().GetWindowHandle(); return(DestroyWindow(handle)); }
private void InitializeFieldsAndCefIfRequired() { if (!initialized) { if (!Cef.IsInitialized && !Cef.Initialize(new CefSettings())) { throw new InvalidOperationException("Cef::Initialize() failed"); } Cef.AddDisposable(this); if (FocusHandler == null) { //If the WinForms UI thread and the CEF UI thread are one in the same //then we don't need the FocusHandler, it's only required when using //MultiThreadedMessageLoop (the default) if (!Cef.CurrentlyOnThread(CefThreadIds.TID_UI)) { FocusHandler = new DefaultFocusHandler(); } } if (browserSettings == null) { browserSettings = new BrowserSettings(frameworkCreated: true); } managedCefBrowserAdapter = new ManagedCefBrowserAdapter(this, false); initialized = true; } }
/// <summary> /// Initializes a new instance of the <see cref="WritableBitmapRenderHandler"/> class. /// </summary> /// <param name="dpiX">The dpi x.</param> /// <param name="dpiY">The dpi y.</param> /// <param name="invalidateDirtyRect">if true then only the direct rectangle will be updated, otherwise the whole bitmap will be redrawn</param> /// <param name="dispatcherPriority">priority at which the bitmap will be updated on the UI thread</param> public DirectWritableBitmapRenderHandler(double dpiX, double dpiY, bool invalidateDirtyRect = true, DispatcherPriority dispatcherPriority = DispatcherPriority.Render) { if (!Cef.CurrentlyOnThread(CefThreadIds.TID_UI)) { throw new NotSupportedException("Can only be used when CEF is integrated into your WPF Message Loop (MultiThreadedMessageLoop = false)."); } this.dpiX = dpiX; this.dpiY = dpiY; this.invalidateDirtyRect = invalidateDirtyRect; }
public override void LoadExtension(string rootDirectory, string manifestJson, IExtensionHandler handler) { if (Cef.CurrentlyOnThread(CefThreadIds.TID_UI)) { base.LoadExtension(rootDirectory, manifestJson, handler); } else { Cef.UIThreadTaskFactory.StartNew(() => { base.LoadExtension(rootDirectory, manifestJson, handler); }); } }
private static async void MainAsync(string cachePath, double zoomLevel) { var browserSettings = new BrowserSettings(); //Reduce rendering speed to one frame per second so it's easier to take screen shots browserSettings.WindowlessFrameRate = 1; var requestContextSettings = new RequestContextSettings { CachePath = cachePath }; // RequestContext can be shared between browser instances and allows for custom settings // e.g. CachePath using (var requestContext = new RequestContext(requestContextSettings)) using (var browser = new ChromiumWebBrowser(TestUrl, browserSettings, requestContext)) { if (zoomLevel > 1) { browser.FrameLoadStart += (s, argsi) => { var b = (ChromiumWebBrowser)s; if (argsi.Frame.IsMain) { b.SetZoomLevel(zoomLevel); } }; } await LoadPageAsync(browser); //Check preferences on the CEF UI Thread await Cef.UIThreadTaskFactory.StartNew(delegate { var preferences = requestContext.GetAllPreferences(true); //Check do not track status var doNotTrack = (bool)preferences["enable_do_not_track"]; Debug.WriteLine("DoNotTrack:" + doNotTrack); }); var onUi = Cef.CurrentlyOnThread(CefThreadIds.TID_UI); // For Google.com pre-pupulate the search text box await browser.EvaluateScriptAsync("document.getElementById('lst-ib').value = 'CefSharp Was Here!'"); // Wait for the screenshot to be taken, // if one exists ignore it, wait for a new one to make sure we have the most up to date await browser.ScreenshotAsync(true).ContinueWith(DisplayBitmap); await LoadPageAsync(browser, "http://github.com"); //Gets a wrapper around the underlying CefBrowser instance var cefBrowser = browser.GetBrowser(); // Gets a warpper around the CefBrowserHost instance // You can perform a lot of low level browser operations using this interface var cefHost = cefBrowser.GetHost(); //You can call Invalidate to redraw/refresh the image cefHost.Invalidate(PaintElementType.View); // Wait for the screenshot to be taken. await browser.ScreenshotAsync(true).ContinueWith(DisplayBitmap); } }
public async Task MainAsync(GraphicsDevice gd, IntPtr windowHandle, string url, object data, System.Drawing.Size size, double zoomLevel = 1.0) { if (Browser != null) { Browser.NewFrame -= Browser_NewFrame; Browser.Dispose(); } var browserSettings = new BrowserSettings(); //Reduce rendering speed to one frame per second so it's easier to take screen shots browserSettings.WindowlessFrameRate = 30; var requestContextSettings = new RequestContextSettings { CachePath = CachePath }; // RequestContext can be shared between browser instances and allows for custom settings // e.g. CachePath RequestContext = new RequestContext(requestContextSettings); Browser = new MonoCefBrowser(gd, url, browserSettings, RequestContext); Browser.CreateBrowser(new WindowInfo() { WindowHandle = windowHandle, Width = size.Width, Height = size.Height, WindowlessRenderingEnabled = true }, browserSettings); Browser.NewFrame += Browser_NewFrame; Browser.Size = size; if (zoomLevel > 1) { Browser.FrameLoadStart += (s, argsi) => { var b = (ChromiumWebBrowser)s; if (argsi.Frame.IsMain) { b.SetZoomLevel(zoomLevel); } }; } await LoadPageAsync(Browser); //Check preferences on the CEF UI Thread await Cef.UIThreadTaskFactory.StartNew(delegate { var preferences = RequestContext.GetAllPreferences(true); //Check do not track status var doNotTrack = (bool)preferences["enable_do_not_track"]; Debug.WriteLine("DoNotTrack:" + doNotTrack); }); var onUi = Cef.CurrentlyOnThread(CefThreadIds.TID_UI); await LoadPageAsync(Browser, url); //Gets a wrapper around the underlying CefBrowser instance var cefBrowser = Browser.GetBrowser(); // Gets a warpper around the CefBrowserHost instance // You can perform a lot of low level browser operations using this interface var cefHost = cefBrowser.GetHost(); cefHost.SendFocusEvent(true); SetMarshalledData(data); //You can call Invalidate to redraw/refresh the image cefHost.Invalidate(PaintElementType.View); }
private static async Task MainAsync(string url, string cachePath, double zoomLevel) { var browserSettings = new BrowserSettings { //Reduce rendering speed to one frame per second so it's easier to take screen shots WindowlessFrameRate = 1 }; var requestContextSettings = new RequestContextSettings { CachePath = Path.GetFullPath(cachePath) }; // RequestContext can be shared between browser instances and allows for custom settings // e.g. CachePath using (var requestContext = new RequestContext(requestContextSettings)) using (var browser = new ChromiumWebBrowser(url, browserSettings, requestContext)) { if (zoomLevel > 1) { browser.FrameLoadStart += (s, argsi) => { var b = (ChromiumWebBrowser)s; if (argsi.Frame.IsMain) { b.SetZoomLevel(zoomLevel); } }; } await browser.WaitForInitialLoadAsync(); //Check preferences on the CEF UI Thread await Cef.UIThreadTaskFactory.StartNew(delegate { var preferences = requestContext.GetAllPreferences(true); //Check do not track status var doNotTrack = (bool)preferences["enable_do_not_track"]; Debug.WriteLine("DoNotTrack: " + doNotTrack); }); var onUi = Cef.CurrentlyOnThread(CefThreadIds.TID_UI); // For Google.com pre-pupulate the search text box if (url.Contains("google.com")) { await browser.EvaluateScriptAsync("document.querySelector('[name=q]').value = 'CefSharp Was Here!'"); } //Example using SendKeyEvent for input instead of javascript //var browserHost = browser.GetBrowserHost(); //var inputString = "CefSharp Was Here!"; //foreach(var c in inputString) //{ // browserHost.SendKeyEvent(new KeyEvent { WindowsKeyCode = c, Type = KeyEventType.Char }); //} ////Give the browser a little time to finish drawing our SendKeyEvent input //await Task.Delay(100); // Wait for the screenshot to be taken, // if one exists ignore it, wait for a new one to make sure we have the most up to date var bitmap = await browser.ScreenshotAsync(true); DisplayBitmap(bitmap); //await browser.LoadUrlAsync("http://github.com"); // Gets a warpper around the CefBrowserHost instance // You can perform a lot of low level browser operations using this interface //var cefbrowserHost = browser.GetBrowserHost(); //You can call Invalidate to redraw/refresh the image //cefbrowserHost.Invalidate(PaintElementType.View); // Wait for the screenshot to be taken. //bitmap = await browser.ScreenshotAsync(true); //DisplayBitmap(bitmap); } }
/// <summary> /// Calls Page.captureScreenshot without any optional params /// (Results in PNG image of default viewport) /// https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-captureScreenshot /// </summary> /// <param name="browser">the ChromiumWebBrowser</param> /// <returns>png encoded image as byte[]</returns> public static async Task <byte[]> CaptureScreenShotAsPng(this IWebBrowser chromiumWebBrowser) { //if (!browser.HasDocument) //{ // throw new System.Exception("Page hasn't loaded"); //} var host = chromiumWebBrowser.GetBrowserHost(); if (host == null || host.IsDisposed) { throw new Exception("BrowserHost is Null or Disposed"); } //var param = new Dictionary<string, object> //{ // { "format", "png" }, //} var msgId = Interlocked.Increment(ref LastMessageId); var observer = new TaskMethodDevToolsMessageObserver(msgId); //Make sure to dispose of our observer registration when done //TODO: Create a single observer that maps tasks to Id's //Or at least create one for each type, events and method using (var observerRegistration = host.AddDevToolsMessageObserver(observer)) { //Page.captureScreenshot defaults to PNG, all params are optional //for this DevTools method int id = 0; const string methodName = "Page.captureScreenshot"; //TODO: Simplify this, we can use an Func to reduce code duplication if (Cef.CurrentlyOnThread(CefThreadIds.TID_UI)) { id = host.ExecuteDevToolsMethod(msgId, methodName); } else { id = await Cef.UIThreadTaskFactory.StartNew(() => { return(host.ExecuteDevToolsMethod(msgId, methodName)); }); } if (id != msgId) { throw new Exception("Message Id doesn't match the provided Id"); } var result = await observer.Task; var success = result.Item1; dynamic response = JsonConvert.DeserializeObject <dynamic>(Encoding.UTF8.GetString(result.Item2)); //Success if (success) { return(Convert.FromBase64String((string)response.data)); } var code = (string)response.code; var message = (string)response.message; throw new Exception(code + ":" + message); } }
private static async Task MainAsync(string url, string secondUrl, string cachePath, double zoomLevel) { var browserSettings = new BrowserSettings { //Reduce rendering speed to one frame per second so it's easier to take screen shots WindowlessFrameRate = 1 }; var requestContextSettings = new RequestContextSettings { CachePath = Path.GetFullPath(cachePath) }; // RequestContext can be shared between browser instances and allows for custom settings // e.g. CachePath using (var requestContext = new RequestContext(requestContextSettings)) using (var browser = new ChromiumWebBrowser(url, browserSettings, requestContext)) { if (zoomLevel > 1) { browser.FrameLoadStart += (s, argsi) => { var b = (ChromiumWebBrowser)s; if (argsi.Frame.IsMain) { b.SetZoomLevel(zoomLevel); } }; } await browser.WaitForInitialLoadAsync(); //Check preferences on the CEF UI Thread await Cef.UIThreadTaskFactory.StartNew(delegate { var preferences = requestContext.GetAllPreferences(true); //Check do not track status var doNotTrack = (bool)preferences["enable_do_not_track"]; Debug.WriteLine("DoNotTrack: " + doNotTrack); }); var onUi = Cef.CurrentlyOnThread(CefThreadIds.TID_UI); // For Google.com pre-pupulate the search text box if (url.Contains("google.com")) { await browser.EvaluateScriptAsync("document.querySelector('[name=q]').value = 'CefSharp Was Here!'"); } //Example using SendKeyEvent for input instead of javascript //var browserHost = browser.GetBrowserHost(); //var inputString = "CefSharp Was Here!"; //foreach(var c in inputString) //{ // browserHost.SendKeyEvent(new KeyEvent { WindowsKeyCode = c, Type = KeyEventType.Char }); //} ////Give the browser a little time to finish drawing our SendKeyEvent input //await Task.Delay(100); var contentSize = await browser.GetContentSizeAsync(); var viewport = new Viewport { Height = contentSize.Height, Width = contentSize.Width, Scale = 1.0 }; // Wait for the screenshot to be taken, // if one exists ignore it, wait for a new one to make sure we have the most up to date var bitmap = await browser.CaptureScreenshotAsync(viewport : viewport); // Make a file to save it to (e.g. C:\Users\jan\Desktop\CefSharp screenshot.png) var screenshotPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "CefSharp screenshot" + DateTime.Now.Ticks + ".png"); Console.WriteLine(); Console.WriteLine("Screenshot ready. Saving to {0}", screenshotPath); File.WriteAllBytes(screenshotPath, bitmap); Console.WriteLine("Screenshot saved. Launching your default image viewer..."); // Tell Windows to launch the saved image. Process.Start(new ProcessStartInfo(screenshotPath) { // UseShellExecute is false by default on .NET Core. UseShellExecute = true }); await browser.LoadUrlAsync(secondUrl); // Gets a warpper around the CefBrowserHost instance // You can perform a lot of low level browser operations using this interface var cefbrowserHost = browser.GetBrowserHost(); //You can call Invalidate to redraw/refresh the image cefbrowserHost.Invalidate(PaintElementType.View); contentSize = await browser.GetContentSizeAsync(); viewport = new Viewport { Height = contentSize.Height, Width = contentSize.Width, Scale = 1.0 }; // Wait for the screenshot to be taken, // if one exists ignore it, wait for a new one to make sure we have the most up to date bitmap = await browser.CaptureScreenshotAsync(viewport : viewport); screenshotPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "CefSharp screenshot" + DateTime.Now.Ticks + ".png"); Console.WriteLine(); Console.WriteLine("Screenshot ready. Saving to {0}", screenshotPath); File.WriteAllBytes(screenshotPath, bitmap); Console.WriteLine("Screenshot saved. Launching your default image viewer..."); // Tell Windows to launch the saved image. Process.Start(new ProcessStartInfo(screenshotPath) { // UseShellExecute is false by default on .NET Core. UseShellExecute = true }); } }
private static async Task <Bitmap> MainAsync(string cachePath, string url) { var browserSettings = new BrowserSettings(); //Reduce rendering speed to one frame per second so it's easier to take screen shots browserSettings.WindowlessFrameRate = 1; var requestContextSettings = new RequestContextSettings { CachePath = cachePath }; // RequestContext can be shared between browser instances and allows for custom settings // e.g. CachePath using (var requestContext = new RequestContext(requestContextSettings)) using (var browser = new ChromiumWebBrowser(url, browserSettings, requestContext)) { browser.Size = new Size() { Width = PageWidth, Height = PageHeight }; await LoadPageAsync(browser); Thread.Sleep(4000); //Check preferences on the CEF UI Thread //await Cef.UIThreadTaskFactory.StartNew(delegate //{ // var preferences = requestContext.GetAllPreferences(true); // //Check do not track status // var doNotTrack = (bool)preferences["enable_do_not_track"]; // Debug.WriteLine("DoNotTrack:" + doNotTrack); //}); var onUi = Cef.CurrentlyOnThread(CefThreadIds.TID_UI); var task = browser.GetMainFrame().EvaluateScriptAsync("(function() { document.body.style.overflow = 'hidden'; var body = document.body, html = document.documentElement; return Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight ); })();", null); await task.ContinueWith(t => { if (!t.IsFaulted) { var response = t.Result; double height = 0; if (response.Success && response.Result != null && double.TryParse(response.Result.ToString(), out height)) { if (height > PageHeight) { browser.Size = new Size() { Width = PageWidth, Height = (int)height }; } } } }); var task2 = browser.GetMainFrame().EvaluateScriptAsync("(function() { document.body.style.overflow = 'hidden'; })();", null); Bitmap result = null; await task2.ContinueWith(t => { if (!t.IsFaulted) { result = browser.ScreenshotAsync(true).Result;//.ContinueWith(DisplayBitmap).Wait(); browser.Delete(); } }); return(result); } }