Skip to content

Commit 5d0c8ee

Browse files
committed
OffScreen - SelfHost BrowserSubProcess for .Net 5.0 PublishSingleFile
1 parent 6a1fd8c commit 5d0c8ee

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

CefSharp.MinimalExample.OffScreen/CefSharp.MinimalExample.OffScreen.netcore.csproj

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,20 @@
2121
https://github.com/dotnet/docs/issues/12237
2222
-->
2323
<RollForward>Major</RollForward>
24+
<StartupObject>CefSharp.MinimalExample.OffScreen.Program</StartupObject>
25+
</PropertyGroup>
26+
27+
<!--
28+
.Net 5.0 Publish Settings for PublishSingleFile
29+
https://docs.microsoft.com/en-us/dotnet/core/deploying/single-file
30+
Defaults differ compared to .Net Core 3.1
31+
-->
32+
<PropertyGroup Condition="'$(TargetFramework)' == 'net5.0-windows' AND '$(PublishSingleFile)' == 'true'">
33+
<!-- Extract all files to disk at runtime -->
34+
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
35+
<!-- Include our native files in the resulting exe -->
36+
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
37+
<StartupObject>CefSharp.MinimalExample.OffScreen.ProgramPublishSingleFile</StartupObject>
2438
</PropertyGroup>
2539

2640
<PropertyGroup Condition="'$(PlatformTarget)' == 'x86'">
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// Copyright © 2021 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+
5+
using CefSharp.OffScreen;
6+
using System;
7+
using System.Diagnostics;
8+
using System.IO;
9+
using System.Threading;
10+
using System.Threading.Tasks;
11+
12+
namespace CefSharp.MinimalExample.OffScreen
13+
{
14+
/// <summary>
15+
/// For .Net 5.0 Publishing Single File exe requires using your own applications executable to
16+
/// act as the BrowserSubProcess. See https://github.com/cefsharp/CefSharp/issues/3407
17+
/// for further details. <see cref="Program.Main(string[])"/> for the default main application entry point
18+
/// </summary>
19+
public class ProgramPublishSingleFile
20+
{
21+
private static ChromiumWebBrowser browser;
22+
23+
public static int Main(string[] args)
24+
{
25+
//To support High DPI this must be before CefSharp.BrowserSubprocess.SelfHost.Main so the BrowserSubprocess is DPI Aware
26+
Cef.EnableHighDPISupport();
27+
28+
//Self Hosting the BrowserSucProcess
29+
var exitCode = CefSharp.BrowserSubprocess.SelfHost.Main(args);
30+
31+
if (exitCode >= 0)
32+
{
33+
return exitCode;
34+
}
35+
36+
const string testUrl = "https://www.google.com/";
37+
38+
Console.WriteLine("This example application will load {0}, take a screenshot, and save it to your desktop.", testUrl);
39+
Console.WriteLine("You may see Chromium debugging output, please wait...");
40+
Console.WriteLine();
41+
42+
var settings = new CefSettings()
43+
{
44+
//By default CefSharp will use an in-memory cache, you need to specify a Cache Folder to persist data
45+
CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache"),
46+
BrowserSubprocessPath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName
47+
};
48+
49+
//Perform dependency check to make sure all relevant resources are in our output directory.
50+
Cef.Initialize(settings, performDependencyCheck: false);
51+
52+
// Create the offscreen Chromium browser.
53+
browser = new ChromiumWebBrowser(testUrl);
54+
55+
// An event that is fired when the first page is finished loading.
56+
// This returns to us from another thread.
57+
browser.LoadingStateChanged += BrowserLoadingStateChanged;
58+
59+
// We have to wait for something, otherwise the process will exit too soon.
60+
Console.ReadKey();
61+
62+
// Clean up Chromium objects. You need to call this in your application otherwise
63+
// you will get a crash when closing.
64+
Cef.Shutdown();
65+
66+
return 0;
67+
}
68+
69+
private static void BrowserLoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
70+
{
71+
// Check to see if loading is complete - this event is called twice, one when loading starts
72+
// second time when it's finished
73+
// (rather than an iframe within the main frame).
74+
if (!e.IsLoading)
75+
{
76+
// Remove the load event handler, because we only want one snapshot of the initial page.
77+
browser.LoadingStateChanged -= BrowserLoadingStateChanged;
78+
79+
var scriptTask = browser.EvaluateScriptAsync("document.querySelector('[name=q]').value = 'CefSharp Was Here!'");
80+
81+
scriptTask.ContinueWith(t =>
82+
{
83+
//Give the browser a little time to render
84+
Thread.Sleep(500);
85+
// Wait for the screenshot to be taken.
86+
var task = browser.ScreenshotAsync();
87+
task.ContinueWith(x =>
88+
{
89+
// Make a file to save it to (e.g. C:\Users\jan\Desktop\CefSharp screenshot.png)
90+
var screenshotPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "CefSharp screenshot.png");
91+
92+
Console.WriteLine();
93+
Console.WriteLine("Screenshot ready. Saving to {0}", screenshotPath);
94+
95+
// Save the Bitmap to the path.
96+
// The image type is auto-detected via the ".png" extension.
97+
task.Result.Save(screenshotPath);
98+
99+
// We no longer need the Bitmap.
100+
// Dispose it to avoid keeping the memory alive. Especially important in 32-bit applications.
101+
task.Result.Dispose();
102+
103+
Console.WriteLine("Screenshot saved. Launching your default image viewer...");
104+
105+
// Tell Windows to launch the saved image.
106+
Process.Start(new ProcessStartInfo(screenshotPath)
107+
{
108+
// UseShellExecute is false by default on .NET Core.
109+
UseShellExecute = true
110+
});
111+
112+
Console.WriteLine("Image viewer launched. Press any key to exit.");
113+
}, TaskScheduler.Default);
114+
});
115+
}
116+
}
117+
}
118+
}

0 commit comments

Comments
 (0)