Disclosure Statement: This site contains affiliate links, which means that I may receive a commission if you make a purchase using these links. As an eBay Partner, I earn from qualifying purchases.
Calling cef_shutdown() restarts the application
Calling cef_shutdown() restarts the application
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.
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.
- salvadordf
- Posts: 4079
- Joined: Thu Feb 02, 2017 12:24 pm
- Location: Spain
- Contact:
Re: Calling cef_shutdown() restarts the application
I've never seen that. This could be an issue in the DPR code.
Please, provide a code sample to reproduce that issue.
Please, provide a code sample to reproduce that issue.
Re: Calling cef_shutdown() restarts the application
Hi Salvador,
This is my DPR code.
And this is the TCEFApplicationHandler2D:
And this is my code for TCEFApplicationHandler_Abstract
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;
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;
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;
- salvadordf
- Posts: 4079
- Joined: Thu Feb 02, 2017 12:24 pm
- Location: Spain
- Contact:
Re: Calling cef_shutdown() restarts the application
Sorry for the delay.
I added most of your code to the SimpleBrowser2 demo to make some tests. I added this unit :
The DPR looked like this :
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.
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.
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.
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
Hi,
I did test this in SimpleBrowser2 by using cefdebuglog to check if the application restarts. See the modified dpr code below:
And I did get a log that shows the following:
I am using Delphi 10.3 and Windows 10. I wonder if you could reproduce this issue.
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.
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!
- salvadordf
- Posts: 4079
- Joined: Thu Feb 02, 2017 12:24 pm
- Location: Spain
- Contact:
Re: Calling cef_shutdown() restarts the application
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.
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
Thank you for checking. Kudos for this library!
Re: Calling cef_shutdown() restarts the application
Hi Salvador,
Just a followup question. What is the quick fix to disable the restart?
Just a followup question. What is the quick fix to disable the restart?
- salvadordf
- Posts: 4079
- Joined: Thu Feb 02, 2017 12:24 pm
- Location: Spain
- Contact:
Re: Calling cef_shutdown() restarts the application
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.
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
Ok, thank you again.