-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
/
Copy pathBrowserSubprocessExecutable.h
165 lines (146 loc) · 8.07 KB
/
BrowserSubprocessExecutable.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// Copyright © 2019 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "SubProcess.h"
using namespace System;
using namespace CefSharp::Internals;
namespace CefSharp
{
namespace BrowserSubprocess
{
/// <summary>
/// BrowserSubprocessExecutable provides the fundimental browser process handling for
/// CefSharp.BrowserSubprocess.exe and can be used to self host the BrowserSubProcess in your
/// existing application (preferred approach for .Net Core).
/// </summary>
public ref class BrowserSubprocessExecutable
{
public:
BrowserSubprocessExecutable()
{
}
#ifdef NETCOREAPP
/// <summary>
/// This function should be called from the application entry point function (typically Program.Main)
/// to execute a secondary process e.g. gpu, renderer, utility
/// This overload is specifically used for .Net Core. For hosting your own BrowserSubProcess
/// it's preferable to use the Main method provided by this class.
/// </summary>
/// <returns>
/// If called for the browser process (identified by no "type" command-line value) it will return immediately
/// with a value of -1. If called for a recognized secondary process it will block until the process should exit
/// and then return the process exit code.
/// </returns
static int MainSelfHost(array<String^>^ args)
{
auto subProcess = gcnew BrowserSubprocessExecutable();
return subProcess->Main(args, nullptr);
}
#endif
/// <summary>
/// This function should be called from the application entry point function (typically Program.Main)
/// to execute a secondary process e.g. gpu, renderer, utility
/// This overload is specifically used for .Net Core. For hosting your own BrowserSubProcess
/// it's preferable to use the Main method provided by this class.
/// - Obtains the command line args via a call to Environment::GetCommandLineArgs
/// </summary>
/// <returns>
/// If called for the browser process (identified by no "type" command-line value) it will return immediately
/// with a value of -1. If called for a recognized secondary process it will block until the process should exit
/// and then return the process exit code.
/// </returns
static int MainNetCore(IntPtr arg, int argLength)
{
auto args = Environment::GetCommandLineArgs();
auto subProcess = gcnew BrowserSubprocessExecutable();
return subProcess->Main(args, nullptr);
}
/// <summary>
/// This function should be called from the application entry point function (typically Program.Main)
/// to execute a secondary process e.g. gpu, renderer, utility
/// It can be used to run secondary processes (BrowserSubProcess) from your main applications executable
/// or from a separate executable specified by the CefSettings.BrowserSubprocessPath value.
/// CefSharp defaults to using the latter approach, a default implementation (CefSharp.BrowserSubProcess.exe) is
/// supplied, see https://github.com/cefsharp/CefSharp/wiki/General-Usage#processes for more details.
/// </summary>
/// <param name="args">command line args</param>
/// <returns>
/// If called for the browser process (identified by no "type" command-line value) it will return immediately
/// with a value of -1. If called for a recognized secondary process it will block until the process should exit
/// and then return the process exit code.
/// </returns
int Main(IEnumerable<String^>^ args)
{
return Main(args, nullptr);
}
/// <summary>
/// This function should be called from the application entry point function (typically Program.Main)
/// to execute a secondary process e.g. gpu, renderer, utility
/// It can be used to run secondary processes (BrowserSubProcess) from your main applications executable
/// or from a separate executable specified by the CefSettings.BrowserSubprocessPath value.
/// CefSharp defaults to using the latter approach, a default implementation (CefSharp.BrowserSubProcess.exe) is
/// supplied, see https://github.com/cefsharp/CefSharp/wiki/General-Usage#processes for more details.
/// </summary>
/// <param name="args">command line args</param>
/// <param name="handler">An option IRenderProcessHandler implementation, use null if no handler is required</param>
/// <returns>
/// If called for the browser process (identified by no "type" command-line value) it will return immediately
/// with a value of -1. If called for a recognized secondary process it will block until the process should exit
/// and then return the process exit code.
/// </returns>
int Main(IEnumerable<String^>^ args, IRenderProcessHandler^ handler)
{
auto type = CommandLineArgsParser::GetArgumentValue(args, CefSharpArguments::SubProcessTypeArgument);
if (String::IsNullOrEmpty(type))
{
//If --type param missing from command line CEF/Chromium assums
//this is the main process (as all subprocesses must have a type param).
//Return -1 to indicate this behaviour.
return -1;
}
auto parentProcessId = -1;
// The Crashpad Handler doesn't have any HostProcessIdArgument, so we must not try to
// parse it lest we want an ArgumentNullException.
if (type == "crashpad-handler")
{
//Lower the shutdown priority so the browser process is shutdown first (Issue #3155)
//The system terminates the process without displaying a retry dialog box for the user.
//Crashpad is lower than other sub processes so it can still monitor process exit crashes.
SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY);
}
else
{
//Lower the shutdown priority so the browser process is shutdown first (Issue #3155)
//The system terminates the process without displaying a retry dialog box for the user.
SetProcessShutdownParameters(0x200, SHUTDOWN_NORETRY);
parentProcessId = int::Parse(CommandLineArgsParser::GetArgumentValue(args, CefSharpArguments::HostProcessIdArgument));
if (CommandLineArgsParser::HasArgument(args, CefSharpArguments::ExitIfParentProcessClosed))
{
ParentProcessMonitor::StartMonitorTask(parentProcessId);
}
}
// Use our custom subProcess provides features like EvaluateJavascript
if (type == "renderer")
{
auto subProcess = GetSubprocess(args, parentProcessId, handler);
try
{
return subProcess->Run();
}
finally
{
delete subProcess;
}
}
return SubProcess::ExecuteProcess(args);
}
protected:
virtual SubProcess^ GetSubprocess(IEnumerable<String^>^ args, int parentProcessId, IRenderProcessHandler^ handler)
{
return gcnew SubProcess(handler, args);
}
};
}
}