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.

SendProcessMessage to Main Process doesn't work

Albus

SendProcessMessage to Main Process doesn't work

Post by Albus »

Hi, currently I'm trying to send a Message from the sub process to the main process.

I have the following function, which is called in the central Execute() function by the JavaScript callback

Code: Select all

  function SendExecuteToMainProcess: Boolean;
  var
    ProcMsg : ICefProcessMessage;
    counter: Integer;
    value: ICefv8Value;
  begin
    ProcMsg := TCefProcessMessageRef.New(MSG_EXECUTE_TO_MAIN);
    ProcMsg.ArgumentList.SetString(0, name);
    //ProcMsg.ArgumentList.SetValue(1, Cefv8ToCef(obj));
    ProcMsg.ArgumentList.SetInt(1, Length(arguments));
    counter := 2;
    for value in arguments do
    begin
      ProcMsg.ArgumentList.SetValue(counter, Cefv8ToCef(value));
      counter := counter + 1;
    end;

    Result := TCefv8ContextRef.Current.Browser.SendProcessMessage(PID_BROWSER, ProcMsg);
  end;
And the messages were supposed to be delivered here

Code: Select all

procedure TDVCefBridge.RenderProcessHandler_OnProcessMessageReceivedEvent(const pBrowser       : ICefBrowser;
                                                                                uSourceProcess : TCefProcessId;
                                                                          const pMessage       : ICefProcessMessage);
var
  callName: string;
  callObj: ICefv8Value;
  callArguments: TCefv8ValueArray;

  caLength: Integer;
  i: Integer;
begin
  ShowMessage(IntToStr(GetCurrentProcessId));

  CefLog('CEF4Delphi', 1, CEF_LOG_SEVERITY_INFO, 'OnProcessMessageReceivedEvent Begin');
  if (pMessage = nil) or (pMessage.ArgumentList = nil) then exit;

  if pMessage.Name = MSG_EXECUTE_TO_MAIN then
  begin

    callName := pMessage.ArgumentList.GetString(0);
    //callObj := CefToCefv8(pMessage.ArgumentList.GetValue(1));
    caLength := pMessage.ArgumentList.GetInt(1);

    SetLength(callArguments, caLength);
    for i := 0 to caLength-1 do
      callArguments[i] := CefToCefv8(pMessage.ArgumentList.GetValue(i + 2));

  end;

  CefLog('CEF4Delphi', 1, CEF_LOG_SEVERITY_INFO, 'OnProcessMessageReceivedEvent End');
end;
Here I register the ProcessHandler

Code: Select all

  FIsMainProcess := False;
  FProcessHandler := TCefCustomRenderProcessHandler.Create;
  FProcessHandler.OnWebKitInitializedEvent := ProcessHandler_OnWebKitInitializedEvent;
  FProcessHandler.AddMessageName(MSG_EXECUTE_TO_MAIN);
  FProcessHandler.OnProcessMessageReceivedEvent := Instance.RenderProcessHandler_OnProcessMessageReceivedEvent;

  GlobalCEFApp := TCefApplication.Create;
  [...]
  GlobalCEFApp.RenderProcessHandler := FProcessHandler as ICefRenderProcessHandler;
  FIsMainProcess := GlobalCEFApp.StartMainProcess;
But the ProcessHandler receives nothing. And I don't know where the mistake might be.
User avatar
salvadordf
Posts: 4057
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: SendProcessMessage to Main Process doesn't work

Post by salvadordf »

Thanks for the bug report!

I'll take a look as soon as I can but right now I'm very busy. :(
Albus

Re: SendProcessMessage to Main Process doesn't work

Post by Albus »

I just realized that I'm using an old version of cef. I'm now updating to the latest version and try it angaint (currently I have problems with some restructuration of the delphi classes and some exceptions)
Albus

Re: SendProcessMessage to Main Process doesn't work

Post by Albus »

Now I've updated cef, but the problem is the same. Is it possible that this is not working (getting the browser from the TCefv8ContextRef):

Code: Select all

Result := TCefv8ContextRef.Current.Browser.SendProcessMessage(PID_BROWSER, ProcMsg);
User avatar
salvadordf
Posts: 4057
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: SendProcessMessage to Main Process doesn't work

Post by salvadordf »

Please, set GlobalCEFApp.SingleProcess to TRUE (just for this debugging session) and set some breakpoints inside the functions receiving the messages.

While trying to find the cause of another bug I fixed a problem in the parameter handling that prevented the execution of TCefv8ValueRef.ExecuteFunction and TCefv8ValueRef.ExecuteFunctionWithContext

Let me know If you were using those functions and I'll upload the fix to GitHub.
Albus

Re: SendProcessMessage to Main Process doesn't work

Post by Albus »

In single process mode the process messages are not fired (because there it makes no sense). But I debugged with my IDE inside the subprocess. And inside the subprocess everything works fine and the SendProcessMessage function returns True. But the message just doesn't came through to the ProcessMessageReceived function

But currently i have an other problem, because everytime I try to start my app, i get an access violation inside the libcef.dll. I figured out that this exception only comes if I register an Extension inside OnWebkitInitialized.

Code: Select all

code := '__defineGetter__(''app'', function(){native function $get();return $get()});';
CefRegisterExtension('app', code, TDVCefBridge.Instance as ICefv8Handler);
I have this error since updating Cef4Delphi to the latest version. Then I could fix it with using '"this."__defineGetter__[...]'. But know even with this I get an exception.

And I use neither TCefv8ValueRef.ExecuteFunction nor TCefv8ValueRef.ExecuteFunctionWithContext in my own code
User avatar
salvadordf
Posts: 4057
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: SendProcessMessage to Main Process doesn't work

Post by salvadordf »

Try to register the extension the same way the JSExtension or JSRTTIExtension demos do.

If CEF doesn't like the code you try to register it just crashes. That's why TCefRTTIExtension.Register used to crash a few months ago.
Albus

Re: SendProcessMessage to Main Process doesn't work

Post by Albus »

salvadordf wrote: Tue Mar 20, 2018 4:22 pm Try to register the extension the same way the JSExtension or JSRTTIExtension demos do.

If CEF doesn't like the code you try to register it just crashes. That's why TCefRTTIExtension.Register used to crash a few months ago.
Thank you, I've found out that I just forgot an inherited; inside the Create of my ExtensionHandler (and the "this." in the Extension JavaScript).

Unfortunately the original error still occurs. I made an other test and debuged with two IDEs simultaneously. One for the main process and one for the subprocess. And it confirmed that the message is not transported from the subprocess to the main process.
I made an other test and sent a message from the main process to the subprocess and it worked fine.

In the subprocess i use following line to send the message

Code: Select all

Result := TCefv8ContextRef.Current.Browser.SendProcessMessage(PID_BROWSER, ProcMsg);
Is it possible that

Code: Select all

TCefv8ContextRef.Current.Browser
doesn't return the correct browser? Is there an other way to get the browser handle from inside the subprocess (in the Execute() function of TCefv8HandlerOwn)?
User avatar
salvadordf
Posts: 4057
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: SendProcessMessage to Main Process doesn't work

Post by salvadordf »

This might be related to this problem :
http://magpcss.org/ceforum/viewtopic.php?f=6&t=15677

Please, check if you navigated to a different domain.
Also, set GlobalCEFApp.SitePerProcess to FALSE.
Albus

Re: SendProcessMessage to Main Process doesn't work

Post by Albus »

I set GlobalCefApp.SitePerProcess to False but nothing changed. And I don't navigate to a different domain. I load a local html file at startup ('file:///C:/.../demo.html') with some buttons on it. And the button click triggers the cef extension.
Post Reply