Page 1 of 1
Calling cef_shutdown() restarts the application
Posted: Mon Apr 20, 2020 11:37 am
by lasaranza
Hi,
I noticed that when I destroy the GlobalCEFApp using DestroyGlobalCEFApp() procedure, the application restarts itself when cef_shutdown() in TCefApplicationCore.ShutDown is called. When the application restarts the GlobalCEFApp.StartMainProcess() returns false, that made the application to close by itself. I encountered the same behaviour in DCEF3 when using multi-processes. I wanted to confirm is this is a default behaviour or known issue?
Thank you.
Re: Calling cef_shutdown() restarts the application
Posted: Mon Apr 20, 2020 3:03 pm
by salvadordf
I've never seen that. This could be an issue in the DPR code.
Please, provide a code sample to reproduce that issue.
Re: Calling cef_shutdown() restarts the application
Posted: Tue Apr 21, 2020 8:12 am
by lasaranza
Hi Salvador,
This is my DPR code.
Code: Select all
TCEFApplicationHandler2D.StartGlobalCEF();
try
if not TCEFApplicationHandler2D.StartMainProcess() then
EXIT;
Application.Initialize();
Application.MainFormOnTaskbar := True;
Application.CreateForm(TfrmMain, frmMain);
Application.Run();
finally
TCEFApplicationHandler2D.ShutdownGlobalCEF();
end;
And this is the TCEFApplicationHandler2D:
Code: Select all
TCEFApplicationHandler2D = class(TCEFApplicationHandler_Abstract)
strict protected
class constructor ClassCreate();
class destructor ClassDestroy();
end;
class constructor TCEFApplicationHandler2D.ClassCreate();
begin
FInstance := TCEFApplicationHandler2D.Create();
end;
class destructor TCEFApplicationHandler2D.ClassDestroy();
begin
FreeAndNil(FInstance);
end;
And this is my code for TCEFApplicationHandler_Abstract
Code: Select all
TCEFApplicationHandler_Abstract = class
strict private
class var FInstance: TCEFApplicationHandler_Abstract;
public
constructor Create();
destructor Destroy(); override;
class function StartMainProcess(): Boolean;
class procedure StartGlobalCEF();
class procedure ShutdownGlobalCEF();
end;
constructor TCEFApplicationHandler_Abstract.Create();
begin
if Assigned(FInstance) then
raise EPlxCEFApplicationException.CreateFmt('%s is a singleton class and is already instantiated before.', [ClassName]);
inherited Create();
end;
destructor TCEFApplicationHandler_Abstract.Destroy();
begin
DestroyGlobalCEFApp();
inherited Destroy();
end;
class procedure TCEFApplicationHandler_Abstract.StartGlobalCEF();
begin
if not Assigned(FInstance) then
raise EPlxCEFApplicationException.Create('Cannot start GlobalCEFApp from abstract class!');
GlobalCEFApp := TCefApplication.Create();
GlobalCEFApp.FrameworkDirPath := 'dcef';
GlobalCEFApp.ResourcesDirPath := 'dcef';
GlobalCEFApp.OnRegCustomSchemes := RegisterSchemes; // code not added here
GlobalCEFApp.OnBrowserCreated := HandleOnBrowserCreated; // code not added here
GlobalCEFApp.OnWebKitInitialized := HandleOnWebKitInitialized; // code not added here
end;
class procedure TCEFApplicationHandler_Abstract.ShutdownGlobalCEF();
begin
DestroyGlobalCEFApp();
end;
class function TCEFApplicationHandler_Abstract.StartMainProcess(): Boolean;
begin
Result := GlobalCEFApp.StartMainProcess();
end;
Re: Calling cef_shutdown() restarts the application
Posted: Thu Apr 23, 2020 8:41 am
by salvadordf
Sorry for the delay.
I added most of your code to the SimpleBrowser2 demo to make some tests. I added this unit :
Code: Select all
unit uCEFApplicationHandler;
interface
type
TCEFApplicationHandler_Abstract = class
protected
class var FInstance: TCEFApplicationHandler_Abstract;
public
constructor Create();
destructor Destroy(); override;
class function StartMainProcess(): Boolean;
class procedure StartGlobalCEF();
class procedure ShutdownGlobalCEF();
end;
TCEFApplicationHandler2D = class(TCEFApplicationHandler_Abstract)
strict protected
class constructor ClassCreate();
class destructor ClassDestroy();
end;
implementation
uses
SysUtils,
uCEFApplication;
constructor TCEFApplicationHandler_Abstract.Create();
begin
if Assigned(FInstance) then
raise Exception.Create('TCEFApplicationHandler_Abstract.Create error : assigned FInstance');
inherited Create();
end;
destructor TCEFApplicationHandler_Abstract.Destroy();
begin
DestroyGlobalCEFApp();
inherited Destroy();
end;
class procedure TCEFApplicationHandler_Abstract.StartGlobalCEF();
begin
if not Assigned(FInstance) then
raise Exception.Create('TCEFApplicationHandler_Abstract.StartGlobalCEF error : assigned FInstance');
GlobalCEFApp := TCefApplication.Create();
// GlobalCEFApp.FrameworkDirPath := 'dcef';
// GlobalCEFApp.ResourcesDirPath := 'dcef';
// GlobalCEFApp.OnRegCustomSchemes := RegisterSchemes; // code not added here
// GlobalCEFApp.OnBrowserCreated := HandleOnBrowserCreated; // code not added here
// GlobalCEFApp.OnWebKitInitialized := HandleOnWebKitInitialized; // code not added here
end;
class procedure TCEFApplicationHandler_Abstract.ShutdownGlobalCEF();
begin
DestroyGlobalCEFApp();
end;
class function TCEFApplicationHandler_Abstract.StartMainProcess(): Boolean;
begin
Result := GlobalCEFApp.StartMainProcess();
end;
class constructor TCEFApplicationHandler2D.ClassCreate();
begin
FInstance := TCEFApplicationHandler2D.Create();
end;
class destructor TCEFApplicationHandler2D.ClassDestroy();
begin
FreeAndNil(FInstance);
end;
end.
The DPR looked like this :
Code: Select all
program SimpleBrowser2;
{$I cef.inc}
uses
Vcl.Forms,
uSimpleBrowser2 in 'uSimpleBrowser2.pas' {Form1},
uCEFApplicationHandler in 'uCEFApplicationHandler.pas';
{$R *.res}
begin
TCEFApplicationHandler2D.StartGlobalCEF();
try
if not TCEFApplicationHandler2D.StartMainProcess() then
EXIT;
Application.Initialize();
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run();
finally
TCEFApplicationHandler2D.ShutdownGlobalCEF();
end;
end.
The uSimpleBrowser2 unit wasn't modified.
I run the demo in Delphi 10.3.3 and it worked correctly with the latest CEF4Delphi version.
Seeing your TCEFApplicationHandler2D class makes me think that your application has a complicated initialization. Perhaps this issue could be solved (or at least identified) if you use a different EXE for the CEF subprocesses.
Take a look at the "
SubProcess" demo for more details.
Re: Calling cef_shutdown() restarts the application
Posted: Fri Apr 24, 2020 2:25 pm
by lasaranza
Hi,
I did test this in SimpleBrowser2 by using cefdebuglog to check if the application restarts. See the modified dpr code below:
Code: Select all
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.LogFile := 'debug.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
if GlobalCEFApp.StartMainProcess then
begin
CefDebugLog('Start main process!');
Application.Initialize;
{$IFDEF DELPHI11_UP}
Application.MainFormOnTaskbar := True;
{$ENDIF}
Application.CreateForm(TForm1, Form1);
Application.Run;
end
else
begin
CefDebugLog('Cannot start main process!');
end;
CefDebugLog('Shutting down!');
GlobalCEFApp.Free;
GlobalCEFApp := nil;
end.
And I did get a log that shows the following:
Code: Select all
[0424/162123.163:ERROR:CEF4Delphi(1)] PID: 12864, TID: 10868, PT: Browser - Start main process!
[0424/162141.471:ERROR:CEF4Delphi(1)] PID: 12864, TID: 10868, PT: Browser - Shutting down!
[0424/162141.490:ERROR:CEF4Delphi(1)] PID: 22172, TID: 30532, PT: Other - Cannot start main process!
[0424/162141.491:ERROR:CEF4Delphi(1)] PID: 22172, TID: 30532, PT: Other - Shutting down!
I am using Delphi 10.3 and Windows 10. I wonder if you could reproduce this issue.
Re: Calling cef_shutdown() restarts the application
Posted: Sat Apr 25, 2020 2:54 pm
by salvadordf
Thanks for reporting this!
I just added a missing process type to the CefDebugLog procedure and updated CEF4Delphi.
The last process in that log is in fact a "
Utility" process also known as a "
Network Service" process.
That's a normal Chromium process and as all other subprocesses, it's handled internally in Chromium's code.
Re: Calling cef_shutdown() restarts the application
Posted: Sat Apr 25, 2020 7:32 pm
by lasaranza
Thank you for checking. Kudos for this library!
Re: Calling cef_shutdown() restarts the application
Posted: Tue Apr 28, 2020 3:40 pm
by lasaranza
Hi Salvador,
Just a followup question. What is the quick fix to disable the restart?
Re: Calling cef_shutdown() restarts the application
Posted: Tue Apr 28, 2020 3:58 pm
by salvadordf
I would try to use a different EXE for the subprocesses as shown in the SubProcess demo.
It seems that your application has a complex initialization. In those cases it's recommended to use a different EXE to avoid issues like this one.
Re: Calling cef_shutdown() restarts the application
Posted: Tue Apr 28, 2020 6:50 pm
by lasaranza
Ok, thank you again.