PageRenderTime 318ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/CefSharp.Example/CefExample.cs

https://github.com/cefsharp/CefSharp
C# | 324 lines | 185 code | 49 blank | 90 comment | 11 complexity | 6c28191cf862358cb5783630689ed6db MD5 | raw file
Possible License(s): BSD-3-Clause
  1. // Copyright © 2014 The CefSharp Authors. All rights reserved.
  2. //
  3. // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
  4. using System;
  5. using System.Diagnostics;
  6. using System.IO;
  7. using System.Runtime.InteropServices;
  8. using System.Text;
  9. using CefSharp.Example.Proxy;
  10. using CefSharp.SchemeHandler;
  11. namespace CefSharp.Example
  12. {
  13. public static class CefExample
  14. {
  15. //TODO: Revert after https://bitbucket.org/chromiumembedded/cef/issues/2685/networkservice-custom-scheme-unable-to
  16. //has been fixed.
  17. public const string ExampleDomain = "cefsharp.example";
  18. public const string BaseUrl = "https://" + ExampleDomain;
  19. public const string DefaultUrl = BaseUrl + "/home.html";
  20. #if NETCOREAPP
  21. public const string BindingTestUrl = BaseUrl + "/BindingTestNetCore.html";
  22. #else
  23. public const string BindingTestUrl = BaseUrl + "/BindingTest.html";
  24. #endif
  25. public const string BindingTestNetCoreUrl = BaseUrl + "/BindingTestNetCore.html";
  26. public const string BindingTestSingleUrl = BaseUrl + "/BindingTestSingle.html";
  27. public const string BindingTestsAsyncTaskUrl = BaseUrl + "/BindingTestsAsyncTask.html";
  28. public const string LegacyBindingTestUrl = BaseUrl + "/LegacyBindingTest.html";
  29. public const string PostMessageTestUrl = BaseUrl + "/PostMessageTest.html";
  30. public const string PluginsTestUrl = BaseUrl + "/plugins.html";
  31. public const string PopupTestUrl = BaseUrl + "/PopupTest.html";
  32. public const string TooltipTestUrl = BaseUrl + "/TooltipTest.html";
  33. public const string BasicSchemeTestUrl = BaseUrl + "/SchemeTest.html";
  34. public const string ResponseFilterTestUrl = BaseUrl + "/ResponseFilterTest.html";
  35. public const string DraggableRegionTestUrl = BaseUrl + "/DraggableRegionTest.html";
  36. public const string DragDropCursorsTestUrl = BaseUrl + "/DragDropCursorsTest.html";
  37. public const string CssAnimationTestUrl = BaseUrl + "/CssAnimationTest.html";
  38. public const string CdmSupportTestUrl = BaseUrl + "/CdmSupportTest.html";
  39. public const string HelloWorldUrl = BaseUrl + "/HelloWorld.html";
  40. public const string BindingApiCustomObjectNameTestUrl = BaseUrl + "/BindingApiCustomObjectNameTest.html";
  41. public const string TestResourceUrl = "http://test/resource/load";
  42. public const string RenderProcessCrashedUrl = "http://processcrashed";
  43. public const string TestUnicodeResourceUrl = "http://test/resource/loadUnicode";
  44. public const string PopupParentUrl = "http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_win_close";
  45. public const string ChromeInternalUrls = "chrome://chrome-urls";
  46. public const string ChromeNetInternalUrls = "chrome://net-internals";
  47. public const string ChromeProcessInternalUrls = "chrome://process-internals";
  48. // Use when debugging the actual SubProcess, to make breakpoints etc. inside that project work.
  49. private static readonly bool DebuggingSubProcess = Debugger.IsAttached;
  50. private static string PluginInformation = "";
  51. public static void Init(CefSettingsBase settings, IBrowserProcessHandler browserProcessHandler)
  52. {
  53. // Set Google API keys, used for Geolocation requests sans GPS. See http://www.chromium.org/developers/how-tos/api-keys
  54. // Environment.SetEnvironmentVariable("GOOGLE_API_KEY", "");
  55. // Environment.SetEnvironmentVariable("GOOGLE_DEFAULT_CLIENT_ID", "");
  56. // Environment.SetEnvironmentVariable("GOOGLE_DEFAULT_CLIENT_SECRET", "");
  57. //Chromium Command Line args
  58. //http://peter.sh/experiments/chromium-command-line-switches/
  59. //NOTE: Not all relevant in relation to `CefSharp`, use for reference purposes only.
  60. //CEF specific command line args
  61. //https://bitbucket.org/chromiumembedded/cef/src/master/libcef/common/cef_switches.cc?fileviewer=file-view-default
  62. //**IMPORTANT**: For enabled/disabled command line arguments like disable-gpu specifying a value of "0" like
  63. //settings.CefCommandLineArgs.Add("disable-gpu", "0"); will have no effect as the second argument is ignored.
  64. //**IMPORTANT**: When using command line arguments the behaviour may change between Chromium versions, if you are experiencing
  65. //issues after upgrading to a newer version, you should remove all custom command line arguments and add test them in
  66. //isolation to determine if they are causing issues.
  67. //The command line arguments shown here are here as a reference only and are not tested to confirm they work with each version
  68. settings.RemoteDebuggingPort = 8088;
  69. //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.
  70. //HTML5 databases such as localStorage will only persist across sessions if a cache path is specified.
  71. settings.RootCachePath = Path.GetFullPath("cache");
  72. //If non-null then CachePath must be equal to or a child of RootCachePath
  73. //We're using a sub folder.
  74. //
  75. settings.CachePath = Path.GetFullPath("cache\\global");
  76. //settings.UserAgent = "CefSharp Browser" + Cef.CefSharpVersion; // Example User Agent
  77. //settings.CefCommandLineArgs.Add("renderer-startup-dialog");
  78. //settings.CefCommandLineArgs.Add("enable-media-stream"); //Enable WebRTC
  79. //settings.CefCommandLineArgs.Add("no-proxy-server"); //Don't use a proxy server, always make direct connections. Overrides any other proxy server flags that are passed.
  80. //settings.CefCommandLineArgs.Add("debug-plugin-loading"); //Dumps extra logging about plugin loading to the log file.
  81. //settings.CefCommandLineArgs.Add("disable-plugins-discovery"); //Disable discovering third-party plugins. Effectively loading only ones shipped with the browser plus third-party ones as specified by --extra-plugin-dir and --load-plugin switches
  82. //settings.CefCommandLineArgs.Add("allow-running-insecure-content"); //By default, an https page cannot run JavaScript, CSS or plugins from http URLs. This provides an override to get the old insecure behavior. Only available in 47 and above.
  83. //https://peter.sh/experiments/chromium-command-line-switches/#disable-site-isolation-trials
  84. //settings.CefCommandLineArgs.Add("disable-site-isolation-trials");
  85. //NOTE: Running the Network Service in Process is not something CEF officially supports
  86. //It may or may not work for newer versions.
  87. //settings.CefCommandLineArgs.Add("enable-features", "CastMediaRouteProvider,NetworkServiceInProcess");
  88. //settings.CefCommandLineArgs.Add("enable-logging"); //Enable Logging for the Renderer process (will open with a cmd prompt and output debug messages - use in conjunction with setting LogSeverity = LogSeverity.Verbose;)
  89. //settings.LogSeverity = LogSeverity.Verbose; // Needed for enable-logging to output messages
  90. //settings.CefCommandLineArgs.Add("disable-extensions"); //Extension support can be disabled
  91. //settings.CefCommandLineArgs.Add("disable-pdf-extension"); //The PDF extension specifically can be disabled
  92. //Audo play example
  93. //settings.CefCommandLineArgs["autoplay-policy"] = "no-user-gesture-required";
  94. //NOTE: For OSR best performance you should run with GPU disabled:
  95. // `--disable-gpu --disable-gpu-compositing --enable-begin-frame-scheduling`
  96. // (you'll loose WebGL support but gain increased FPS and reduced CPU usage).
  97. // http://magpcss.org/ceforum/viewtopic.php?f=6&t=13271#p27075
  98. //https://bitbucket.org/chromiumembedded/cef/commits/e3c1d8632eb43c1c2793d71639f3f5695696a5e8
  99. //NOTE: The following function will set all three params
  100. //settings.SetOffScreenRenderingBestPerformanceArgs();
  101. //settings.CefCommandLineArgs.Add("disable-gpu");
  102. //settings.CefCommandLineArgs.Add("disable-gpu-compositing");
  103. //settings.CefCommandLineArgs.Add("enable-begin-frame-scheduling");
  104. //settings.CefCommandLineArgs.Add("disable-gpu-vsync"); //Disable Vsync
  105. // The following options control accessibility state for all frames.
  106. // These options only take effect if accessibility state is not set by IBrowserHost.SetAccessibilityState call.
  107. // --force-renderer-accessibility enables browser accessibility.
  108. // --disable-renderer-accessibility completely disables browser accessibility.
  109. //settings.CefCommandLineArgs.Add("force-renderer-accessibility");
  110. //settings.CefCommandLineArgs.Add("disable-renderer-accessibility");
  111. //Enables Uncaught exception handler
  112. settings.UncaughtExceptionStackSize = 10;
  113. //Disable WebAssembly
  114. //settings.JavascriptFlags = "--noexpose_wasm";
  115. // Off Screen rendering (WPF/Offscreen)
  116. if (settings.WindowlessRenderingEnabled)
  117. {
  118. //Disable Direct Composition to test https://github.com/cefsharp/CefSharp/issues/1634
  119. //settings.CefCommandLineArgs.Add("disable-direct-composition");
  120. // DevTools doesn't seem to be working when this is enabled
  121. // http://magpcss.org/ceforum/viewtopic.php?f=6&t=14095
  122. //settings.CefCommandLineArgs.Add("enable-begin-frame-scheduling");
  123. }
  124. var proxy = ProxyConfig.GetProxyInformation();
  125. switch (proxy.AccessType)
  126. {
  127. case InternetOpenType.Direct:
  128. {
  129. //Don't use a proxy server, always make direct connections.
  130. settings.CefCommandLineArgs.Add("no-proxy-server");
  131. break;
  132. }
  133. case InternetOpenType.Proxy:
  134. {
  135. settings.CefCommandLineArgs.Add("proxy-server", proxy.ProxyAddress);
  136. break;
  137. }
  138. case InternetOpenType.PreConfig:
  139. {
  140. settings.CefCommandLineArgs.Add("proxy-auto-detect");
  141. break;
  142. }
  143. }
  144. //settings.LogSeverity = LogSeverity.Verbose;
  145. //Experimental setting see https://bitbucket.org/chromiumembedded/cef/issues/2969/support-chrome-windows-with-cef-callbacks
  146. //for details
  147. //settings.ChromeRuntime = true;
  148. if (DebuggingSubProcess)
  149. {
  150. var architecture = RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant();
  151. #if NETCOREAPP
  152. settings.BrowserSubprocessPath = Path.GetFullPath("..\\..\\..\\..\\..\\..\\CefSharp.BrowserSubprocess\\bin.netcore\\" + architecture + "\\Debug\\netcoreapp3.1\\CefSharp.BrowserSubprocess.exe");
  153. #else
  154. settings.BrowserSubprocessPath = Path.GetFullPath("..\\..\\..\\..\\CefSharp.BrowserSubprocess\\bin\\" + architecture + "\\Debug\\CefSharp.BrowserSubprocess.exe");
  155. #endif
  156. }
  157. settings.CookieableSchemesList = "custom";
  158. settings.RegisterScheme(new CefCustomScheme
  159. {
  160. SchemeName = CefSharpSchemeHandlerFactory.SchemeName,
  161. SchemeHandlerFactory = new CefSharpSchemeHandlerFactory(),
  162. IsSecure = true, //treated with the same security rules as those applied to "https" URLs
  163. });
  164. settings.RegisterScheme(new CefCustomScheme
  165. {
  166. SchemeName = "https",
  167. SchemeHandlerFactory = new CefSharpSchemeHandlerFactory(),
  168. DomainName = ExampleDomain
  169. });
  170. settings.RegisterScheme(new CefCustomScheme
  171. {
  172. SchemeName = CefSharpSchemeHandlerFactory.SchemeNameTest,
  173. SchemeHandlerFactory = new CefSharpSchemeHandlerFactory(),
  174. IsSecure = true //treated with the same security rules as those applied to "https" URLs
  175. });
  176. //You can use the http/https schemes - best to register for a specific domain
  177. settings.RegisterScheme(new CefCustomScheme
  178. {
  179. SchemeName = "https",
  180. SchemeHandlerFactory = new CefSharpSchemeHandlerFactory(),
  181. DomainName = "cefsharp.com",
  182. IsSecure = true //treated with the same security rules as those applied to "https" URLs
  183. });
  184. const string cefSharpExampleResourcesFolder =
  185. #if !NETCOREAPP
  186. @"..\..\..\..\CefSharp.Example\Resources";
  187. #else
  188. @"..\..\..\..\..\..\CefSharp.Example\Resources";
  189. #endif
  190. settings.RegisterScheme(new CefCustomScheme
  191. {
  192. SchemeName = "localfolder",
  193. SchemeHandlerFactory = new FolderSchemeHandlerFactory(rootFolder: cefSharpExampleResourcesFolder,
  194. schemeName: "localfolder", //Optional param no schemename checking if null
  195. hostName: "cefsharp", //Optional param no hostname checking if null
  196. defaultPage: "home.html") //Optional param will default to index.html
  197. });
  198. //This must be set before Cef.Initialized is called
  199. CefSharpSettings.FocusedNodeChangedEnabled = true;
  200. //Async Javascript Binding - methods are queued on TaskScheduler.Default.
  201. //Set this to true to when you have methods that return Task<T>
  202. //CefSharpSettings.ConcurrentTaskExecution = true;
  203. //Legacy Binding Behaviour - Same as Javascript Binding in version 57 and below
  204. //See issue https://github.com/cefsharp/CefSharp/issues/1203 for details
  205. //CefSharpSettings.LegacyJavascriptBindingEnabled = true;
  206. //Exit the subprocess if the parent process happens to close
  207. //This is optional at the moment
  208. //https://github.com/cefsharp/CefSharp/pull/2375/
  209. CefSharpSettings.SubprocessExitIfParentProcessClosed = true;
  210. //NOTE: Set this before any calls to Cef.Initialize to specify a proxy with username and password
  211. //One set this cannot be changed at runtime. If you need to change the proxy at runtime (dynamically) then
  212. //see https://github.com/cefsharp/CefSharp/wiki/General-Usage#proxy-resolution
  213. //CefSharpSettings.Proxy = new ProxyOptions(ip: "127.0.0.1", port: "8080", username: "cefsharp", password: "123");
  214. bool performDependencyCheck = !DebuggingSubProcess;
  215. if (!Cef.Initialize(settings, performDependencyCheck: performDependencyCheck, browserProcessHandler: browserProcessHandler))
  216. {
  217. throw new Exception("Unable to Initialize Cef");
  218. }
  219. Cef.AddCrossOriginWhitelistEntry(BaseUrl, "https", "cefsharp.com", false);
  220. }
  221. public static async void RegisterTestResources(IWebBrowser browser)
  222. {
  223. if (browser.ResourceRequestHandlerFactory == null)
  224. {
  225. browser.ResourceRequestHandlerFactory = new ResourceRequestHandlerFactory();
  226. }
  227. var handler = browser.ResourceRequestHandlerFactory as ResourceRequestHandlerFactory;
  228. if (handler != null)
  229. {
  230. const string renderProcessCrashedBody = "<html><body><h1>Render Process Crashed</h1><p>Your seeing this message as the render process has crashed</p></body></html>";
  231. handler.RegisterHandler(RenderProcessCrashedUrl, ResourceHandler.GetByteArray(renderProcessCrashedBody, Encoding.UTF8));
  232. const string responseBody = "<html><body><h1>Success</h1><p>This document is loaded from a System.IO.Stream</p></body></html>";
  233. handler.RegisterHandler(TestResourceUrl, ResourceHandler.GetByteArray(responseBody, Encoding.UTF8));
  234. const string unicodeResponseBody = "<html><body>整体满意度</body></html>";
  235. handler.RegisterHandler(TestUnicodeResourceUrl, ResourceHandler.GetByteArray(unicodeResponseBody, Encoding.UTF8));
  236. if (string.IsNullOrEmpty(PluginInformation))
  237. {
  238. var pluginBody = new StringBuilder();
  239. pluginBody.Append("<html><body><h1>Plugins</h1><table>");
  240. pluginBody.Append("<tr>");
  241. pluginBody.Append("<th>Name</th>");
  242. pluginBody.Append("<th>Description</th>");
  243. pluginBody.Append("<th>Version</th>");
  244. pluginBody.Append("<th>Path</th>");
  245. pluginBody.Append("</tr>");
  246. var plugins = await Cef.GetPlugins();
  247. if (plugins.Count == 0)
  248. {
  249. pluginBody.Append("<tr>");
  250. pluginBody.Append("<td colspan='4'>Cef.GetPlugins returned an empty list - likely no plugins were loaded on your system</td>");
  251. pluginBody.Append("</tr>");
  252. pluginBody.Append("<tr>");
  253. pluginBody.Append("<td colspan='4'>You may find that NPAPI/PPAPI need to be enabled</td>");
  254. pluginBody.Append("</tr>");
  255. }
  256. else
  257. {
  258. foreach (var plugin in plugins)
  259. {
  260. pluginBody.Append("<tr>");
  261. pluginBody.Append("<td>" + plugin.Name + "</td>");
  262. pluginBody.Append("<td>" + plugin.Description + "</td>");
  263. pluginBody.Append("<td>" + plugin.Version + "</td>");
  264. pluginBody.Append("<td>" + plugin.Path + "</td>");
  265. pluginBody.Append("</tr>");
  266. }
  267. }
  268. pluginBody.Append("</table></body></html>");
  269. PluginInformation = pluginBody.ToString();
  270. }
  271. handler.RegisterHandler(PluginsTestUrl, ResourceHandler.GetByteArray(PluginInformation, Encoding.UTF8));
  272. }
  273. }
  274. }
  275. }