From cda78d0f344b13c4812513c5822670d320e093dc Mon Sep 17 00:00:00 2001 From: Alex Maitland Date: Sat, 13 Jan 2024 13:23:01 +1000 Subject: [PATCH] Core - Add IBrowserProcessHandler.OnAlreadyRunningAppRelaunch Issue #4668 --- CefSharp.Core.Runtime/Internals/CefSharpApp.h | 30 +++++++++++++++ CefSharp/Handler/BrowserProcessHandler.cs | 38 +++++++++++++++++++ CefSharp/Handler/IBrowserProcessHandler.cs | 29 ++++++++++++++ 3 files changed, 97 insertions(+) diff --git a/CefSharp.Core.Runtime/Internals/CefSharpApp.h b/CefSharp.Core.Runtime/Internals/CefSharpApp.h index 794f523258..f4cfffc7f5 100644 --- a/CefSharp.Core.Runtime/Internals/CefSharpApp.h +++ b/CefSharp.Core.Runtime/Internals/CefSharpApp.h @@ -121,6 +121,36 @@ namespace CefSharp _app->BrowserProcessHandler->OnScheduleMessagePumpWork(delay_ms); } + virtual bool OnAlreadyRunningAppRelaunch(CefRefPtr commandLine, const CefString& currentDirectory) override + { + if (Object::ReferenceEquals(_app, nullptr) || Object::ReferenceEquals(_app->BrowserProcessHandler, nullptr)) + { + return false; + } + + auto managedArgs = gcnew Dictionary(); + + CefCommandLine::ArgumentList args; + commandLine->GetArguments(args); + + for (auto arg : args) + { + managedArgs->Add(StringUtils::ToClr(arg), String::Empty); + } + + CefCommandLine::SwitchMap switches; + commandLine->GetSwitches(switches); + + for (auto s : switches) + { + managedArgs->Add(StringUtils::ToClr(s.first), StringUtils::ToClr(s.second)); + } + + auto readOnlyArgs = gcnew System::Collections::ObjectModel::ReadOnlyDictionary(managedArgs); + + return _app->BrowserProcessHandler->OnAlreadyRunningAppRelaunch(readOnlyArgs, StringUtils::ToClr(currentDirectory)); + } + virtual void OnBeforeChildProcessLaunch(CefRefPtr commandLine) override { #ifndef NETCOREAPP diff --git a/CefSharp/Handler/BrowserProcessHandler.cs b/CefSharp/Handler/BrowserProcessHandler.cs index ea2d8f1fe7..3605cfde30 100644 --- a/CefSharp/Handler/BrowserProcessHandler.cs +++ b/CefSharp/Handler/BrowserProcessHandler.cs @@ -3,6 +3,7 @@ // 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; namespace CefSharp.Handler { @@ -55,6 +56,43 @@ protected virtual void OnScheduleMessagePumpWork(long delay) } + /// + bool IBrowserProcessHandler.OnAlreadyRunningAppRelaunch(IReadOnlyDictionary commandLine, string currentDirectory) + { + return OnAlreadyRunningAppRelaunch(commandLine, currentDirectory); + } + + /// + /// Implement this method to provide app-specific behavior when an already + /// running app is relaunched with the same CefSettings.RootCachePath value. + /// For example, activate an existing app window or create a new app window. + /// + /// To avoid cache corruption only a single app instance is allowed to run for + /// a given CefSettings.RootCachePath value. On relaunch the app checks a + /// process singleton lock and then forwards the new launch arguments to the + /// already running app process before exiting early. Client apps should + /// therefore check the Cef.Initialize() return value for early exit before + /// proceeding. + /// + /// It's important to note that this method will be called on a CEF UI thread, + /// which by default is not the same as your application UI thread. + /// + /// + /// Command line arugments/switches + /// current directory (optional) + /// + /// Return true if the relaunch is handled or false for default relaunch + /// behavior. Default behavior will create a new default styled Chrome window. + /// + /// + /// The dictionary may contain keys that have empty string values + /// (arugments). + /// + protected virtual bool OnAlreadyRunningAppRelaunch(IReadOnlyDictionary commandLine, string currentDirectory) + { + return false; + } + /// /// IsDisposed /// diff --git a/CefSharp/Handler/IBrowserProcessHandler.cs b/CefSharp/Handler/IBrowserProcessHandler.cs index d5b9688993..7d5a635584 100644 --- a/CefSharp/Handler/IBrowserProcessHandler.cs +++ b/CefSharp/Handler/IBrowserProcessHandler.cs @@ -3,6 +3,7 @@ // 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; namespace CefSharp { @@ -34,5 +35,33 @@ public interface IBrowserProcessHandler : IDisposable /// specified delay and any currently pending scheduled call should be /// cancelled. void OnScheduleMessagePumpWork(long delay); + + /// + /// Implement this method to provide app-specific behavior when an already + /// running app is relaunched with the same CefSettings.RootCachePath value. + /// For example, activate an existing app window or create a new app window. + /// + /// To avoid cache corruption only a single app instance is allowed to run for + /// a given CefSettings.RootCachePath value. On relaunch the app checks a + /// process singleton lock and then forwards the new launch arguments to the + /// already running app process before exiting early. Client apps should + /// therefore check the Cef.Initialize() return value for early exit before + /// proceeding. + /// + /// It's important to note that this method will be called on a CEF UI thread, + /// which by default is not the same as your application UI thread. + /// + /// + /// Readonly command line args + /// current directory (optional) + /// + /// Return true if the relaunch is handled or false for default relaunch + /// behavior. Default behavior will create a new default styled Chrome window. + /// + /// + /// The dictionary may contain keys that have empty string values + /// (arugments). + /// + bool OnAlreadyRunningAppRelaunch(IReadOnlyDictionary commandLine, string currentDirectory); } }