-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Trouble Shooting
Using the Chromium Embedded Framework(CEF)
is not an easy task by any stretch of the imagination. It's a complex process fitting something as powerful and feature rich as the entire Chrome browser into as small as possible Windows DLL for others to make use of in their own programs.
Because of this complexity things frequently can go wrong, and to many developers who are just used to plugging components together it can seem like the world in front of them has just fallen into a huge crater.
It doesn't have to be like this though, The CefSharp
community realize that folks are going to have issues, and they do what they can to help, since they do this voluntarily however they may not always be there when you need them to be.
As a result this page is being added to the Wiki in order to help you help yourself when facing problems using CefSharp
.
Initially the page is going to be split into sections, starting with coverage of Windows Forms (WinForms) and at a later date any WPF specific notes too.
Even though the page is going to be split however, much of what applies to WinForms
does also apply to WPF. This means that WPF users should also refer to the WinForms
specific notes too as these will still be beneficial to helping them solve their issues.
1) Platform Target
You must select either x86 or x64 when using the NuGet
packages. If you select AnyCPU the NuGet magic won't work currently.
2) Dependencies still not showing up after adding the Nuget
packages?
Try closing Visual Studio (not just the solution) and then reopen, some of the Nuget
black magic used to import the VC++
dll's doesn't always play nice with Visual Studio.
The biggest problem that seems to be encountered by developers using CefSharp
in their own applications is that the browser does not appear when programmed to do so.
There are a number of reasons for this, some are already outlined elsewhere, but will be repeated here for completeness.
1) Did you initialize the CefSharp Libraries correctly?
Before you can do anything at all with CefSharp
you MUST ensure that you've initialized things correctly.
In the main repository there is a "Simple WinForms Example" that should serve as a template to how this is done correctly. In essence however it boils down to creating a settings object, ensuring that the browser sub process property is set correctly, then calling the main initialization function using these settings.
The following code will do this for you:
Cef.Initialize(new CefSettings());
Remember to also include "using CefSharp;" at the beginning of your code file, so that the correct references can be resolved.
You can easily add this to your "Program.cs" file in a WinForms
application as follows:
using System;
using System.Windows.Forms;
using CefSharp;
namespace CefBlog3
{
static class Program
{
[STAThread]
static void Main()
{
Cef.Initialize(new CefSettings());
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
Remembering to substitute 'Form1' for the name of your main form class.
2) Where are you calling the initial invocation of the browser?
If you need to have the browser not display at startup, then you simply need to pass in an empty string when creating the object, and all you'll receive is a blank browser window.
As above, the simple WinForms
demo shows how to do this correctly, using the following bit of code:
browser = new ChromiumWebBrowser("www.google.com")
{
Dock = DockStyle.Fill,
};
toolStripContainer.ContentPanel.Controls.Add(browser);
Replace the 'www.google.com' string with something like 'string.Empty' if you don't want to load anything initially.
You'll notice in the above example, that the browser is loaded into a 'toolStripContainer' this is also an important point to note, and is covered in the next check point.
3) Where are you trying to render the browser?
There are many examples out there on the internet that show the browser being added to an application's window by adding it directly to the controls collection of the form.
In the older versions of CefSharp this was the main accepted way of doing things, and on the whole of it this does still work.
However, in some edge cases when doing things this way the browser does not render correctly, often re-appearing when the form is re-sized leading to the belief that the problem cause is actually point number 2 above.
It's therefore recommended that you render the browser into a WinForms
panel or similar object, there are two very good reasons for this.
a) The panel allows you to control the browser size, it will never overflow a panel component, but if attached to a form will attempt to use the full form surface often appearing behind regular win-form controls.
b) You can hide the browser (For example if you didn't want to show it at start up) by simply hiding the panel
Rendering into a common component gives you much more control over the render surface allowing you to do many more things not possible when adding direct to the forms controls.
4) Have you included 'CefSharp.BrowserSubprocess.exe' in your output folder?
This one usually seems quite mysterious.
Everything appears to work correctly, all the required code is present, and yet still nothing appears. No exceptions are thrown and everything looks normal.
If the EXE is missing from your output folder, but all the DLL's and other dependencies are present then the WinForms
subsystem will not throw any kind of error indicating anything is wrong, this is one of those problems that can have you going around in ever decreasing circles until the penny suddenly drops.
While your checking for the existence of the EXE stub, it's also worth making sure that you have all the other dependencies there too, some of them are optional and are only used when you ask the browser to do certain things.
Usually however if a DLL dependency is missing, this does result in a missing file exception being thrown.
Still no joy?
If you checked all 4 points above and still can't get the browser output to appear, then there are a couple of other things you can check for a possible cause.
a) In your application output folder be that Debug
or Release
, you'll find a plain text file called 'Debug.Log' in many cases that will actually have in it the error that CEF
encountered when trying to initialize.
b) The developer tools. Add a button to your form and make a call to "browser.ShowDevTools()". If you can see a document has loaded and you have a DOM in there, then your problem is a display output one and your most likely problem is one of not setting 'Dock' correctly, or some other setting is causing the browser to render offscreen/headless. If you get a blank tool window, or no tool window at all, then CefSharp
has failed to initialize correctly, so you have a set-up issue to troubleshoot.
You need to modify your app.manifest
to include a dependency on Microsoft.Windows.Common-Controls
like in the WinForms
example app: https://github.com/cefsharp/CefSharp/blob/master/CefSharp.WinForms.Example/app.manifest#L15
Try enabling ClearType in WPF (source: #1045):
browser.BrowserSettings = new BrowserSettings()
{
OffScreenTransparentBackground = false
};
GPU acceleration is on by default. This creates a dependency on graphics cards and their drivers, which are notoriously unreliable. If you experience slow or quirky rendering, try:
- Disable GPU VSync:
var settings = new CefSharp.CefSettings(); settings.CefCommandLineArgs.Add("disable-gpu-vsync", "1"); Cef.Initialize(settings);
- Disable GPU acceleration:
settings.CefCommandLineArgs.Add("disable-gpu", "1");
- Confirm the command line args have filtered through by starting your app and navigating to this URL:
chrome://version
- Try your app on a different machine, preferably with a different video card.
- Open
chrome://gpu/
inChrome
to see what it says about yourGPU
.
No-nos:
- Do not create
COM
objects on CEF callback threads. This will cause shutdown to freeze. - If you call
Cef.Shutdown()
explicitly, do not do so on a background thread - this may cause a freeze. It must be called on the main thread. - Calling
Application.Exit()
and thenEnvironment.Exit()
will cause a hang - just wait forApplication.Exit()
to finish.
Things to try:
- Call
Cef.Initialize()
very early in your application, rather than letting it be called by the first browser control you create. - Use WinDbg to diagnose what is causing the hang: https://github.com/cefsharp/CefSharp/issues/872#issuecomment-82978118
Related issues:
- https://github.com/cefsharp/CefSharp/issues/820
- https://github.com/cefsharp/CefSharp/issues/872
- https://github.com/cefsharp/CefSharp/issues/990
This section covers debugging and diagnosing native/unmanaged crashes in libcef.dll, BrowserSubProcess, and C++ code in general. When these crashes occur, the C# exception handler does not get called and your application exits. Windows logs an Error event, which you can find the details of using Windows Event Viewer. CEF
also has it's own log file, which by default is called Debug.log
, it will be in your applications executing directory e.g. bin
directory.
Download the Release Symbols
that match the CEF
version you're using from http://opensource.spotify.com/cefbuilds/index.html (or https://cefbuilds.com/ for older version), then extract libcef.dll.pdb
into the executing folder (the same directory as libcef.dll
). It's very important that you match the exact version of CEF
. To identity which version of CEF
your actually using, easiest way is to check your packages.config
file, look for the cef.redist.x86
package, it's version will be something like 3.2526.1362
, that's the exact version of CEF
you'll need to download for comparison. You can also open chrome://version
in the browser to determine the version.
As of version 49
you can download CefSharp
symbols see #1610. If you see an exception in libcef.dll
then focus on getting the CEF
release symbols.
To analyse a crash after the fact check your user profiles AppData\Local\CrashDumps
folder, their is likely a mini crashdump
. See the next section for more details.
You may find it useful to attach the debugger to CefSharp.BrowserSubProcess.exe
, add the following command line option. When the message box opens, attach the debugger to the matching process (should be named Chromium Renderer
). If you have the libcef.dll.pdb
in the same folder as libcef.dll
it should load the symbols successfully an when the app crashes hopefully you will have a more detailed crash stack trace.
settings.CefCommandLineArgs.Add("renderer-startup-dialog", "1");
Check the AppData\Local\CrashDumps
folder for CefSharp.BrowserSubProcess.exe
dumps. Best to load the symbols for libcef.dll
(See above).
To manually generate a crash dump your user can utilize Procdump like this:
procdump -e -ma <binaryname or PID> <dumpfile.dmp>
If your user is on Win 8.1 or later they can use the -r
option for a bit more efficiency in creating the memory dump.
If that command line doesn't do the trick, you might need to use procdump
's -e1
option instead of -e
.
You then load the memory dump into Visual Studio or WinDbg and see what the call stack for the CEF
issue is. (You can google about how to deal with memory dumps and .Net if you haven't done it before.) Our recommendation is to use Visual Studio 2013+ with integrated WinDbg, or WinDbg.
Mozilla - How to get a stacktrace with WinDbg
Will look something like "c:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe" -y . -c ".ecxr;k30;q" -z my_dump_file.dmp
Exception code: 0x4000001f
This is the exception code that occurs when the int 3
instruction is executed.
CEF
is known to do this when you violate its threading restrictions about what executes on which CEF
thread. See CEF Threads for the list of CEF
threads.
If you are lost as to what caused this, reproduce the crash in Visual Studio with symbols loaded.
- http://stackoverflow.com/a/14385526/4583726
- http://vadmyst.blogspot.com.au/2008/01/unmanaged-debugging-option-very-useful.html
-
Google Developers Memory Diagnosis (Please note that
CefSharp
doesn't have aTaskManager
, you can use theDevTools
to troubleshoot memory usage).
Ask on Gitter Chat - Make sure you provide as much detail as possible.