2018-09-10 02:41:13 +02:00
// Copyright © 2014 The CefSharp Authors. All rights reserved.
2014-11-14 18:48:46 +11:00
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
using System ;
2014-11-14 18:19:22 +11:00
using System.Diagnostics ;
using System.IO ;
2014-12-30 10:44:31 +10:00
using System.Threading.Tasks ;
2021-11-16 13:40:39 +10:00
using CefSharp.DevTools.Page ;
2014-11-14 18:19:22 +11:00
2014-11-18 13:15:34 +10:00
namespace CefSharp.OffScreen.Example
2014-11-14 18:19:22 +11:00
{
2014-11-18 13:05:31 +10:00
public class Program
2014-11-14 18:19:22 +11:00
{
2021-10-22 20:10:38 +10:00
private const string TestUrlOne = "https://www.google.com/" ;
private const string TestUrlTwo = "https://github.com/" ;
2021-11-16 13:40:39 +10:00
private const string TestUrlThree = "https://www.google.com/doodles" ;
private const string TestUrlFour = "https://microsoft.com/" ;
2014-11-14 18:19:22 +11:00
2016-12-12 18:46:11 +10:00
public static int Main ( string [ ] args )
2014-11-14 18:19:22 +11:00
{
2021-10-22 20:10:38 +10:00
Console . WriteLine ( "This example application will load {0}, take a screenshot, and save it to your desktop." , TestUrlOne ) ;
2014-11-14 18:19:22 +11:00
Console . WriteLine ( "You may see a lot of Chromium debugging output, please wait..." ) ;
Console . WriteLine ( ) ;
2021-10-22 20:10:38 +10:00
//Console app doesn't have a message loop which we need as Cef.Initialize/Cef.Shutdown must be called on the same
2021-11-16 13:40:39 +10:00
//thread. We use a super simple SynchronizationContext implementation from
2021-10-22 20:10:38 +10:00
//https://devblogs.microsoft.com/pfxteam/await-synchronizationcontext-and-console-apps/
//Continuations will happen on the main thread
//The Nito.AsyncEx.Context Nuget package has a more advanced implementation
//https://github.com/StephenCleary/AsyncEx/blob/8a73d0467d40ca41f9f9cf827c7a35702243abb8/doc/AsyncContext.md#console-example-using-asynccontext
2020-05-04 11:34:52 +10:00
2021-10-22 20:10:38 +10:00
AsyncContext . Run ( async delegate
{
Cef . EnableWaitForBrowsersToClose ( ) ;
2021-11-25 09:45:29 +10:00
var settings = new CefSettings ( ) ;
//The location where cache data will be stored on disk. If empty an in-memory cache will be used for some features and a temporary disk cache for others.
//HTML5 databases such as localStorage will only persist across sessions if a cache path is specified.
settings . CachePath = Path . GetFullPath ( "cache" ) ;
var success = await Cef . InitializeAsync ( settings ) ;
2014-11-14 18:19:22 +11:00
2021-10-22 20:10:38 +10:00
if ( ! success )
{
return ;
}
2014-11-14 18:19:22 +11:00
2021-11-16 13:40:39 +10:00
var t1 = MainAsync ( TestUrlOne , TestUrlTwo , "cache\\path1" , 1.0 ) ;
2021-10-22 20:10:38 +10:00
//Demo showing Zoom Level of 2.0
//Using seperate request contexts allows the urls from the same domain to have independent zoom levels
//otherwise they would be the same - default behaviour of Chromium
2021-11-16 13:40:39 +10:00
var t2 = MainAsync ( TestUrlThree , TestUrlFour , "cache\\path2" , 2.0 ) ;
2014-11-14 18:19:22 +11:00
2021-10-22 20:10:38 +10:00
await Task . WhenAll ( t1 , t2 ) ;
2020-05-04 11:34:52 +10:00
2021-11-16 13:40:39 +10:00
Console . WriteLine ( "Image viewer launched. Press any key to exit." ) ;
2021-10-22 20:10:38 +10:00
// Wait for user input
Console . ReadKey ( ) ;
//Wait until the browser has finished closing (which by default happens on a different thread).
//Cef.EnableWaitForBrowsersToClose(); must be called before Cef.Initialize to enable this feature
//See https://github.com/cefsharp/CefSharp/issues/3047 for details
Cef . WaitForBrowsersToClose ( ) ;
// Clean up Chromium objects. You need to call this in your application otherwise
// you will get a crash when closing.
Cef . Shutdown ( ) ;
} ) ;
2016-12-12 18:46:11 +10:00
//Success
return 0 ;
2014-11-14 18:19:22 +11:00
}
2021-11-16 13:40:39 +10:00
private static async Task MainAsync ( string url , string secondUrl , string cachePath , double zoomLevel )
2014-11-14 18:19:22 +11:00
{
2021-10-22 20:10:38 +10:00
var browserSettings = new BrowserSettings
{
//Reduce rendering speed to one frame per second so it's easier to take screen shots
WindowlessFrameRate = 1
} ;
2020-05-03 16:59:57 +10:00
var requestContextSettings = new RequestContextSettings
{
CachePath = Path . GetFullPath ( cachePath )
} ;
2015-07-22 14:25:10 +10:00
// RequestContext can be shared between browser instances and allows for custom settings
// e.g. CachePath
2018-09-10 02:41:13 +02:00
using ( var requestContext = new RequestContext ( requestContextSettings ) )
2021-10-22 20:10:38 +10:00
using ( var browser = new ChromiumWebBrowser ( url , browserSettings , requestContext ) )
2014-11-14 18:19:22 +11:00
{
2015-07-22 14:25:10 +10:00
if ( zoomLevel > 1 )
2015-07-16 16:44:45 +02:00
{
2015-07-22 14:25:10 +10:00
browser . FrameLoadStart + = ( s , argsi ) = >
2015-07-16 16:44:45 +02:00
{
2015-07-22 14:25:10 +10:00
var b = ( ChromiumWebBrowser ) s ;
2015-09-01 22:48:50 +10:00
if ( argsi . Frame . IsMain )
2015-07-22 14:25:10 +10:00
{
b . SetZoomLevel ( zoomLevel ) ;
}
} ;
}
2021-10-28 10:51:18 +10:00
await browser . WaitForInitialLoadAsync ( ) ;
2014-11-14 18:19:22 +11:00
2016-04-27 20:55:06 +10:00
//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" ] ;
2019-01-10 23:57:28 +01:00
Debug . WriteLine ( "DoNotTrack: " + doNotTrack ) ;
2016-04-27 20:55:06 +10:00
} ) ;
var onUi = Cef . CurrentlyOnThread ( CefThreadIds . TID_UI ) ;
2015-11-27 12:18:56 +10:00
2015-09-10 15:36:40 +10:00
// For Google.com pre-pupulate the search text box
2021-10-22 20:10:38 +10:00
if ( url . Contains ( "google.com" ) )
{
await browser . EvaluateScriptAsync ( "document.querySelector('[name=q]').value = 'CefSharp Was Here!'" ) ;
}
2015-09-10 15:36:40 +10:00
2017-09-15 13:34:02 +10:00
//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);
2021-11-16 13:40:39 +10:00
var contentSize = await browser . GetContentSizeAsync ( ) ;
var viewport = new Viewport
{
Height = contentSize . Height ,
Width = contentSize . Width ,
Scale = 1.0
} ;
2015-09-16 08:41:42 +10:00
// 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
2021-11-16 13:40:39 +10:00
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 ) ;
2021-10-22 20:10:38 +10:00
2021-11-16 13:40:39 +10:00
File . WriteAllBytes ( screenshotPath , bitmap ) ;
2015-04-24 16:00:31 +10:00
2021-11-16 13:40:39 +10:00
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 ) ;
2018-09-10 02:41:13 +02:00
2015-09-16 08:41:42 +10:00
// Gets a warpper around the CefBrowserHost instance
// You can perform a lot of low level browser operations using this interface
2021-11-16 13:40:39 +10:00
var cefbrowserHost = browser . GetBrowserHost ( ) ;
2015-09-16 08:41:42 +10:00
//You can call Invalidate to redraw/refresh the image
2021-11-16 13:40:39 +10:00
cefbrowserHost . Invalidate ( PaintElementType . View ) ;
2015-09-16 08:41:42 +10:00
2021-11-16 13:40:39 +10:00
contentSize = await browser . GetContentSizeAsync ( ) ;
2015-04-24 16:00:31 +10:00
2021-11-16 13:40:39 +10:00
viewport = new Viewport
{
Height = contentSize . Height ,
Width = contentSize . Width ,
Scale = 1.0
} ;
2014-11-14 18:19:22 +11:00
2021-11-16 13:40:39 +10:00
// 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 ) ;
2014-11-14 18:19:22 +11:00
2021-11-16 13:40:39 +10:00
screenshotPath = Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . Desktop ) , "CefSharp screenshot" + DateTime . Now . Ticks + ".png" ) ;
2014-11-14 18:19:22 +11:00
2021-11-16 13:40:39 +10:00
Console . WriteLine ( ) ;
Console . WriteLine ( "Screenshot ready. Saving to {0}" , screenshotPath ) ;
2014-11-14 18:19:22 +11:00
2021-11-16 13:40:39 +10:00
File . WriteAllBytes ( screenshotPath , bitmap ) ;
2014-11-14 18:19:22 +11:00
2021-11-16 13:40:39 +10:00
Console . WriteLine ( "Screenshot saved. Launching your default image viewer..." ) ;
2014-12-30 10:44:31 +10:00
2021-11-16 13:40:39 +10:00
// Tell Windows to launch the saved image.
Process . Start ( new ProcessStartInfo ( screenshotPath )
{
// UseShellExecute is false by default on .NET Core.
UseShellExecute = true
} ) ;
}
2014-11-14 18:19:22 +11:00
}
}
}