// 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"
#include "WcfEnabledSubProcess.h"
using namespace System;
using namespace CefSharp::Internals;
namespace CefSharp
{
namespace BrowserSubprocess
{
///
/// 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).
///
public ref class BrowserSubprocessExecutable
{
public:
BrowserSubprocessExecutable()
{
}
///
/// This function should be called from the application entry point function (typically Program.Main)
/// to execute a secondary process e.g. gpu, plugin, 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
/// - Calls CefEnableHighDPISupport before any other processing
///
///
/// 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.
/// Main(args, nullptr);
}
///
/// This function should be called from the application entry point function (typically Program.Main)
/// to execute a secondary process e.g. gpu, plugin, 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.
///
/// command line args
///
/// 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.
/// ^ args)
{
return Main(args, nullptr);
}
///
/// This function should be called from the application entry point function (typically Program.Main)
/// to execute a secondary process e.g. gpu, plugin, 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.
///
/// command line args
/// An option IRenderProcessHandler implementation, use null if no handler is required
///
/// 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.
///
int Main(IEnumerable^ 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")
{
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^ args, int parentProcessId, IRenderProcessHandler^ handler)
{
return gcnew SubProcess(handler, args);
}
};
}
}