CefWebBrowser creating multiple instances of my application

4,559 views
Skip to first unread message

Fabien Molinet

unread,
Aug 16, 2012, 4:01:37 AM8/16/12
to cef...@googlegroups.com
Hi,

I posted the same message on Cef forum but it doesn't seem to get moderated.

I am using CefGlue in an existing application that we bought. Since this is a big company we can't upgrade IE and are stuck with IE8 .NET WebBrowser that's why I am trying to use CefGlue instead.
I tried to use it like in the example in CefGlue.Client therefore I always have the same bug.
It always ends up giving me a second process which is another instance of my running application. And nothing is displayed it remains blank. 

  • I initialize CEF like that
                CefRuntime.Load();
                var mainArgs = new CefMainArgs(new string[] { });
                var app = new ChromiumApp();
                var exitCode = CefRuntime.ExecuteProcess(mainArgs, app);
                if (exitCode != -1)
                    return; // FMT: throw exception??
                cefSettings = new CefSettings
                {
                    // BrowserSubprocessPath = @"D:\fddima\Projects\Xilium\Xilium.CefGlue\CefGlue.Demo\bin\Release\Xilium.CefGlue.Demo.exe",
                    SingleProcess = false,
                    MultiThreadedMessageLoop = true,
                    LogSeverity = CefLogSeverity.Disable,
                    LogFile = "CefGlue.log",
                };
                CefRuntime.Initialize(mainArgs, cefSettings, app);
                cefInitialized = true;
                if (!cefSettings.MultiThreadedMessageLoop)
                {
                    Application.Idle += OnApplicationIdle;
                }
  • Then I instanciate CefWebBrowser and add it to the controls collection of my form
The second process seems to be created when CefWebBrowser.OnHandleCreated is called. I think it's inside CefBrowserHost.CreateBrowser(windowInfo, client, settings, StartUrl);

Any idea what I am doing wrong ?

Thanks for the help!

Dmitry Azaraev

unread,
Aug 16, 2012, 4:54:43 AM8/16/12
to cef...@googlegroups.com
Hi.

What is problem? In CefGlue.Client it work fine, with multiple browsers.

                if (exitCode != -1)
                    return; // FMT: throw exception??   <<< no, when it is called for main (browser) process it returns immediately with exitCode = -1, if it is renderer process - it is returns only when render process finished.

If you trying run in debug - then you need subprocess other than vs hosting process, or disable hosting process for debug session.

Or may be you doing something wrong.
--
Best regards,
   Dmitry                             mailto:fdd...@gmail.com

Fabien Molinet

unread,
Aug 16, 2012, 5:16:29 AM8/16/12
to cef...@googlegroups.com, dmitry....@gmail.com
Thanks for the feedback Dmitry.
I was running in it debug inside VS so I just tried outside VS but I still get the same issue.

If I run CefGlue.Client it also works fine that's why I don't understand what's going on here.
After being instanciated, the first time the CefWebBrowser is rendered, it always creates a new process of my application and doesn't render anything. I only get a wait cursor when I hover the CefWebBrowser.

The log file doesn't help in my case:
[0816/104634:ERROR:gpu_info_collector_win.cc(93)] Can't retrieve a valid WinSAT assessment.
[0816/104836:WARNING:dns_config_service_win.cc(530)] Failed to read DnsHosts.

Dmitry Azaraev

unread,
Aug 16, 2012, 5:57:48 AM8/16/12
to cef...@googlegroups.com
No have idea.
Give me a repro sample.

Fabien Molinet

unread,
Aug 16, 2012, 6:08:57 AM8/16/12
to cef...@googlegroups.com, dmitry....@gmail.com
Mmmh I can't give a full repro sample since this is part of a bigger application but attached to this message you will have the project I'm currently using.
I used it like that:
var tpTest = tabs.TabPages["tpTest"];
HG.CefGlue.ChromiumBrowser browser = new HG.CefGlue.ChromiumBrowser("http://jsplumb.org/jquery/demo.html");
browser.Dock = DockStyle.Fill;
tpTest.Controls.Add(browser);

I did more tests and even if I configure settings to run in single process it doesn't work.
In single process it doesn't create anymore a copy of the running application. Therefore it doesn't render anything.
In fact on_after_created(cef_life_span_handler_t* self, cef_browser_t* browser) in CefLifeSpanHandler is never called which seems to be the issue.

Have you ever experienced this ?
HG.CefGlue.zip

Dmitry Azaraev

unread,
Aug 16, 2012, 6:37:04 AM8/16/12
to cef...@googlegroups.com
How your Main function looks?

Fabien Molinet

unread,
Aug 16, 2012, 6:56:00 AM8/16/12
to cef...@googlegroups.com, dmitry....@gmail.com
OK I used reflector to get it (since we don't have access to the base code). Here it is :

  [STAThread]
    private static void Main()
    {
        DeferredMain();
        if (_commandLineArgs.Profile)
        {
            WriteLog();
        }
    }

Assembly resolving is also customized but I don't think that's the problem here.

Dmitry Azaraev

unread,
Aug 16, 2012, 7:01:52 AM8/16/12
to cef...@googlegroups.com
Try set browsersubprocesspath to cefclient.exe, and check how it runs.

Fabien Molinet

unread,
Aug 16, 2012, 7:31:10 AM8/16/12
to cef...@googlegroups.com, dmitry....@gmail.com
I did some more tests.

With SingleProcess = true and MultiThreadedMessageLoop = false:
  • using  BrowserSubprocessPath doesn't change anything in my case: outside or inside VS it still doesn't render
  • I suspect that the problem was that Application.Idle never called our OnApplicationIdle... Dunno why.
With SingleProcess = true and MultiThreadedMessageLoop = true: 
  • it works but it isn't related to  BrowserSubprocessPath. If it's there or not it's still working

Dmitry Azaraev

unread,
Aug 16, 2012, 7:49:24 AM8/16/12
to cef...@googlegroups.com
BrowserSubprocessPath related only for multiprocess arch.

On windows using MultiThreadedMessageLoop = true is more applicable, 'cause WinForms doesn't allow inject into message loop, and Application.Idle - called only when application idle, not on each message loop iteration, as actually required. So using Application.Idle is just workaround, which in most cases works fine, expecially with multi-process arch.

But in general looks, like you block one of UI thread, and no messages are received from/to renderer. Browser creates in async way, but it is requires working message loop. May be have sense try creating browser in sync way, it is possible with CefBrowserHost.CreateBrowserSync method. But better is use async way (current).

In any case without working repro i can't help.

Fabien Molinet

unread,
Aug 16, 2012, 7:53:18 AM8/16/12
to cef...@googlegroups.com, dmitry....@gmail.com
Thanks for the explanation it's clearer now.
I won't be able to send you a full repro since it would be way to complicated and the application is around 300Mo so...
But since it's working with SingleProcess and MultiThreadedMessageLoop I think that'll stick with that config.

Dmitry Azaraev

unread,
Aug 16, 2012, 8:00:43 AM8/16/12
to cef...@googlegroups.com
SingleProcess mode exists mainly for easy debugging. I.e. if it is works fine for you, - good, but this mode not officially supported by chromium team, and it contains some potential bugs. So it is better to get working in multiprocess mode, and then having chance to easy switch between them.

> I won't be able to send you a full repro since it would be way to complicated and the application is 
> around 300Mo so...
Repro must be minimal. And of course i no have chance to create repro itself on unknown code.
But in general setting BrowserSubprocessPath to cefclient.exe must work (full qualified path may required). I.e. it is good starting point, to get it work. Later you can create own managed renderer process, if it is required. I.e. while chromium uses same executable for any process kind, in fact they can be different.

Fabien Molinet

unread,
Aug 16, 2012, 9:28:58 AM8/16/12
to cef...@googlegroups.com, dmitry....@gmail.com
I listened to what you said and I'm now using MultiThreaded mode with BrowserSubprocessPath set to the path of Cefclient.exe and it works like a charm.
There's just one "small" issue: when I close the application there are fatal errors.

  • Application.Exit is called
  • CefWebBrowser get disposed
  • <Here is the problem something tries to use CefWebBrowser> --> boom unhandled exception
  • Then I unload CefRuntime
Have you ever experienced this?

Dmitry Azaraev

unread,
Aug 16, 2012, 9:33:36 AM8/16/12
to cef...@googlegroups.com
What exactly exception thrown?
In general you question already contains answer - prevent use browser when it is already disposed.

Fabien Molinet

unread,
Aug 16, 2012, 9:49:01 AM8/16/12
to cef...@googlegroups.com, dmitry....@gmail.com
Yes but I suspect the subprocess or some other internal thread to do that since I don't do much with the CefWebBrowser currently.

Here is the stacktrace :
Invalid window handle
System.ComponentModel.Win32Exception: Invalid window handle
   at MS.Win32.UnsafeNativeMethods.ClientToScreen(HandleRef hWnd, POINT pt)
   at MS.Internal.PointUtil.ClientToScreen(Point pointClient, PresentationSource presentationSource)
   at System.Windows.Input.MouseDevice.GlobalHitTest(Point ptClient, PresentationSource inputSource, IInputElement& enabledHit, IInputElement& originalHit)
   at System.Windows.Input.MouseDevice.PreNotifyInput(Object sender, NotifyInputEventArgs e)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.MouseDevice.Synchronize()
   at System.Windows.Input.MouseDevice.OnHitTestInvalidatedAsync(Object sender, EventArgs e)
   at System.Windows.Input.InputManager.HitTestInvalidatedAsyncCallback(Object arg)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
Exception data:
System.Object:

   at MS.Win32.UnsafeNativeMethods.ClientToScreen(HandleRef hWnd, POINT pt)
   at MS.Internal.PointUtil.ClientToScreen(Point pointClient, PresentationSource presentationSource)
   at System.Windows.Input.MouseDevice.GlobalHitTest(Point ptClient, PresentationSource inputSource, IInputElement& enabledHit, IInputElement& originalHit)
   at System.Windows.Input.MouseDevice.PreNotifyInput(Object sender, NotifyInputEventArgs e)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.MouseDevice.Synchronize()
   at System.Windows.Input.MouseDevice.OnHitTestInvalidatedAsync(Object sender, EventArgs e)
   at System.Windows.Input.InputManager.HitTestInvalidatedAsyncCallback(Object arg)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)

Hope it helps.

Dmitry Azaraev

unread,
Aug 16, 2012, 10:21:37 AM8/16/12
to cef...@googlegroups.com
Looks as problem unrelated to CefGlue, or related very indirectly.
Once window closed - browser will be disposed.
Just for idea, try dispose cefwebbrowser first, in your's ChromiumBrowser.
Reply all
Reply to author
Forward
0 new messages