From d957e361f8b1c81ce4df87f89ccbf7613000307f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Neves?= Date: Thu, 26 Apr 2018 11:24:14 +0100 Subject: [PATCH 1/2] Close cefsharp subprocess if main process dies --- .../WcfEnabledSubProcess.h | 4 +-- CefSharp.BrowserSubprocess/Program.cs | 34 +++++++++++++++---- CefSharp.Core/Internals/CefSharpApp.h | 7 ++-- CefSharp/CefCustomScheme.cs | 5 ++- CefSharp/Internals/CefSharpArguments.cs | 3 +- CefSharp/Internals/CommandLineArgsParser.cs | 11 +++--- 6 files changed, 41 insertions(+), 23 deletions(-) diff --git a/CefSharp.BrowserSubprocess.Core/WcfEnabledSubProcess.h b/CefSharp.BrowserSubprocess.Core/WcfEnabledSubProcess.h index c6b44ff4f5..0148c5a085 100644 --- a/CefSharp.BrowserSubprocess.Core/WcfEnabledSubProcess.h +++ b/CefSharp.BrowserSubprocess.Core/WcfEnabledSubProcess.h @@ -25,9 +25,9 @@ namespace CefSharp Nullable parentProcessId; public: - WcfEnabledSubProcess(IEnumerable^ args) : SubProcess(args) + WcfEnabledSubProcess(int parentProcessId, IEnumerable^ args) : SubProcess(args) { - parentProcessId = CommandLineArgsParser::LocateParentProcessId(args); + this->parentProcessId = parentProcessId; } void OnBrowserCreated(CefBrowserWrapper^ browser) override; diff --git a/CefSharp.BrowserSubprocess/Program.cs b/CefSharp.BrowserSubprocess/Program.cs index ef5b5e9313..22ffa2ba61 100644 --- a/CefSharp.BrowserSubprocess/Program.cs +++ b/CefSharp.BrowserSubprocess/Program.cs @@ -3,9 +3,8 @@ // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; +using System.Threading.Tasks; using CefSharp.Internals; namespace CefSharp.BrowserSubprocess @@ -19,16 +18,16 @@ public static int Main(string[] args) SubProcess.EnableHighDPISupport(); int result; + var type = args.GetArgumentValue(CefSharpArguments.SubProcessTypeArgument); + var parentProcessId = int.Parse(args.GetArgumentValue(CefSharpArguments.HostProcessIdArgument)); - const string typePrefix = "--type="; - var typeArgument = args.SingleOrDefault(arg => arg.StartsWith(typePrefix)); - var type = typeArgument.Substring(typePrefix.Length); + Task.Run(() => AwaitParentProcessExit(parentProcessId)); //Use our custom subProcess provides features like EvaluateJavascript if (type == "renderer") { var wcfEnabled = args.HasArgument(CefSharpArguments.WcfEnabledArgument); - var subProcess = wcfEnabled ? new WcfEnabledSubProcess(args) : new SubProcess(args); + var subProcess = wcfEnabled ? new WcfEnabledSubProcess(parentProcessId, args) : new SubProcess(args); using (subProcess) { @@ -41,8 +40,29 @@ public static int Main(string[] args) } Debug.WriteLine("BrowserSubprocess shutting down."); - + return result; } + + private static void AwaitParentProcessExit(int parentProcessId) + { + try + { + var parentProcess = Process.GetProcessById(parentProcessId); + parentProcess.WaitForExit(); + } + catch (Exception e) + { + //main process probably died already, bailout + Debug.WriteLine(e); + return; + } + + Task.Delay(1000); //wait a bit before exiting + + Debug.WriteLine("BrowserSubprocess shutting down forcibly."); + + Environment.Exit(0); + } } } diff --git a/CefSharp.Core/Internals/CefSharpApp.h b/CefSharp.Core/Internals/CefSharpApp.h index e5c79f3f71..47b47ad53e 100644 --- a/CefSharp.Core/Internals/CefSharpApp.h +++ b/CefSharp.Core/Internals/CefSharpApp.h @@ -58,11 +58,12 @@ namespace CefSharp if (CefSharpSettings::WcfEnabled) { commandLine->AppendArgument(StringUtils::ToNative(CefSharpArguments::WcfEnabledArgument)); - //ChannelId was removed in https://bitbucket.org/chromiumembedded/cef/issues/1912/notreached-in-logchannelidandcookiestores - //We need to know the process Id to establish WCF communication - commandLine->AppendArgument(StringUtils::ToNative(CefSharpArguments::WcfHostProcessIdArgument + "=" + Process::GetCurrentProcess()->Id)); } + //ChannelId was removed in https://bitbucket.org/chromiumembedded/cef/issues/1912/notreached-in-logchannelidandcookiestores + //We need to know the process Id to establish WCF communication and wait for parent process exit + commandLine->AppendArgument(StringUtils::ToNative(CefSharpArguments::HostProcessIdArgument + "=" + Process::GetCurrentProcess()->Id)); + if (_cefSettings->_cefCustomSchemes->Count > 0) { String^ argument = "="; diff --git a/CefSharp/CefCustomScheme.cs b/CefSharp/CefCustomScheme.cs index 9844ceec4c..98aa9fb50f 100644 --- a/CefSharp/CefCustomScheme.cs +++ b/CefSharp/CefCustomScheme.cs @@ -119,13 +119,12 @@ public CefCustomScheme() /// list of scheme objects public static List ParseCommandLineArguments(IEnumerable args) { - var schemes = args.FirstOrDefault(a => a.StartsWith(CefSharpArguments.CustomSchemeArgument)); + var schemes = args.GetArgumentValue(CefSharpArguments.CustomSchemeArgument); var customSchemes = new List(); if (!string.IsNullOrEmpty(schemes)) { - //Remove the "--custom-scheme=" part of the argument - schemes.Substring(CefSharpArguments.CustomSchemeArgument.Length + 1).Split(';').ToList().ForEach(x => + schemes.Split(';').ToList().ForEach(x => { var tokens = x.Split('|'); var customScheme = new CefCustomScheme diff --git a/CefSharp/Internals/CefSharpArguments.cs b/CefSharp/Internals/CefSharpArguments.cs index 40c1d5a030..2020202922 100644 --- a/CefSharp/Internals/CefSharpArguments.cs +++ b/CefSharp/Internals/CefSharpArguments.cs @@ -7,8 +7,9 @@ namespace CefSharp.Internals public static class CefSharpArguments { public const string WcfEnabledArgument = "--wcf-enabled"; - public const string WcfHostProcessIdArgument = "--wcf-host-process-id"; + public const string HostProcessIdArgument = "--host-process-id"; public const string CustomSchemeArgument = "--custom-scheme"; public const string FocusedNodeChangedEnabledArgument = "--focused-node-enabled"; + public const string SubProcessTypeArgument = "--type"; } } diff --git a/CefSharp/Internals/CommandLineArgsParser.cs b/CefSharp/Internals/CommandLineArgsParser.cs index fc3f0bef52..62ca32b02c 100644 --- a/CefSharp/Internals/CommandLineArgsParser.cs +++ b/CefSharp/Internals/CommandLineArgsParser.cs @@ -17,18 +17,15 @@ public static bool HasArgument(this IEnumerable args, string arg) return args.Any(a => a.StartsWith(arg)); } - public static int? LocateParentProcessId(this IEnumerable args) + public static string GetArgumentValue(this IEnumerable args, string argumentName) { - var hostProcessId = args.SingleOrDefault(arg => arg.StartsWith(CefSharpArguments.WcfHostProcessIdArgument)); - if (hostProcessId == null) + var arg = args.FirstOrDefault(a => a.StartsWith(argumentName)); + if (arg == null) { return null; } - var parentProcessId = hostProcessId - .Split('=') - .Last(); - return int.Parse(parentProcessId); + return arg.Split('=').Last(); } } } From 81b7828cbcf2fe3e235825867a4ec41bb2f39521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Neves?= Date: Fri, 3 May 2019 14:33:04 +0100 Subject: [PATCH 2/2] Kill subprocess to avoid hanging on close --- CefSharp.BrowserSubprocess/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CefSharp.BrowserSubprocess/Program.cs b/CefSharp.BrowserSubprocess/Program.cs index 3a27034d17..dae57d3803 100644 --- a/CefSharp.BrowserSubprocess/Program.cs +++ b/CefSharp.BrowserSubprocess/Program.cs @@ -79,7 +79,7 @@ private static async void AwaitParentProcessExit(int parentProcessId) Debug.WriteLine("BrowserSubprocess shutting down forcibly."); - Environment.Exit(0); + Process.GetCurrentProcess().Kill(); } } }