Skip to content
Alex Maitland edited this page Feb 11, 2024 · 50 revisions

For a better understanding of CefSharp please start by reading the General Usage Guide, it covers a range of topics. The General Usage#Need to know/Limitations section has a list of important facts.

Log File

By default CEF has it's own log file, Debug.log which is located in your executing folder. e.g. bin. You can change the path/filename of this log file

var settings = new CefSettings()
{
	LogFile = "Debug.log", //You can customise this path
	LogSeverity = LogSeverity.Default // You can change the log level
};

//Perform dependency check to make sure all relevant resources are in our output directory.
Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);

General Troubleshooting

1) Platform Target

Version 51.0.0 added support for the AnyCPU target, see https://github.com/cefsharp/CefSharp/issues/1714 for details. You can still of course select either x86 or x64 when using the NuGet packages (This is the simplest option). You need to change the Solution Target as this is a current limitation (changing at just the project level is not enough). Pull requests welcome with improvements.

2) Dependencies still not showing up after adding the Nuget packages?

Follow the Post Installation instructions provided in the Nuget Readme.txt (This file would have been opened when you installed the packages).

https://github.com/cefsharp/CefSharp/blob/master/NuGet/Readme.txt#L7

Dependencies

A complex set of dependencies are required, these must be distributed with your application.

https://github.com/cefsharp/CefSharp/wiki/Output-files-description-table-%28Redistribution%29

Installers/Packaging

TODO: ClickOnce (VS Installer) requires additional steps

Initialize

Before instances of ChromiumWebBrowser are created the underlying framework needs to be initialized. If you don't need to configure any settings then this will be done automatically for you by the framework. See https://github.com/cefsharp/CefSharp/wiki/General-Usage#initialize-and-shutdown for more details.

Should you need to specify some settings, like a CachePath (so the browser persists cookies, etc) then you'll need to manually initialize. 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:

//Set the cache path
var settings = new CefSettings() { CachePath = "Cache" };
//Perform dependency check to make sure all relevant resources are in our output directory.
Cef.Initialize(settings , performDependencyCheck: true, browserProcessHandler: null);

Remember to also include the relevant using statements, see below for examples.

using CefSharp;
using CefSharp.Wpf;
using CefSharp;
using CefSharp.WinForms;
using CefSharp;
using CefSharp.OffScreen;

Troubleshooting WinForms

1) 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.

This simple WinForms demo shows how to do this correctly, using the following bit of code:

browser = new ChromiumWebBrowser("www.google.com");
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.

2) 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.

Tooltips don't appear

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

Troubleshooting WPF

Blurry text

Moved to FAQ WPF blurry rendering.

Troubleshooting Graphics, Video or Performance Problems

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 acceleration (see below)
  • Disable GPU VSync (see below)
  • Confirm the command line args have filtered through by starting your app and navigating to this URL: chrome:https://version
  • Try your app on a different machine, preferably with a different video card.
  • Open chrome:https://gpu/ in Chrome to see what it says about your GPU.
var settings = new CefSettings();
settings.CefCommandLineArgs.Add("disable-gpu"); // Disable GPU acceleration
settings.CefCommandLineArgs.Add("disable-gpu-vsync"); //Disable GPU vsync

Cef.Initialize(settings);

Application freezing on shutdown

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 application thread (UI Thread).
  • Calling Application.Exit() and then Environment.Exit() will cause a hang - just wait for Application.Exit() to finish.

Things to try:

Related issues:

Unmanaged crashes (when the process dies)

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.

Crash Reporting

CEF supports the Crashpad crash-reporting system. For generic CEF details on configuring see https://bitbucket.org/chromiumembedded/cef/wiki/CrashReporting.md

Summary
  • Disabled by default
  • Provides many options including creating crash dumps to a folder or server
  • crash_reporter.cfg needs to be placed next to your main application executable.
  • Make sure you set ExternalHandler=CefSharp.BrowserSubprocess.exe otherwise you main application executable will be used (which is supported, just requires additional code in your application)

Example crash_reporter.cfg which generates crash dumps in the "C:\Users\[CurrentUser]\AppData\Local\[AppName]\User Data folder.

# Crash reporting is configured using an INI-style config file named
# "crash_reporter.cfg". This file must be placed next to
# the main application executable. 
# Comments start with a hash character and must be on their own line.
# See https://bitbucket.org/chromiumembedded/cef/wiki/CrashReporting.md
# for further details

[Config]
ProductName=CefSharp.MinimalExample.WinForms
ProductVersion=1.0.0
AppName=CefSharp.MinimalExample
ExternalHandler=CefSharp.BrowserSubprocess.exe

Load one of the following URLs in a ChromiumWebBrowser instance to cause a crash:

  • Main (browser) process crash: chrome:https://inducebrowsercrashforrealz
  • Renderer process crash: chrome:https://crash
  • GPU process crash: chrome:https://gpucrash
  • Out of memory: chrome:https://memory-exhaust/

Loading native symbols, for easier diagnosis

To obtain a meaningful stack trace you need to load the relevant pdb files.

For crashes in libcef.dll

To identity the CEF version use one of the following options:

  • Check the Release Notes here on GitHub.
  • You can also open chrome:https://version in the browser to determine the version.
  • Check your packages.config file, look for the cef.redist.x86 package, it's version will be something like 79.1.36, that's the short version CEF you'll need to download. The full version will look like 79.1.36+g90301bd+chromium-79.0.3945.130

The CefSharp specific symbols are included in the Nuget packages, the pdbs have been generated using GitLink see #1680 for details. GitLink provides you with the ability to step directly into the .Net source directly from your application. If you see an exception in libcef.dll then focus on getting the CEF release symbols.

If you obtain a crashdump from a users computer you can analyze it in Visual Studio at a later point, manually loading the symbols to obtain a symbolized stack trace. If you've never analysed a crashdump before check out https://msdn.microsoft.com/en-us/library/windows/desktop/ee416349(v=vs.85).aspx#analyzing_a_minidump there are also many other resources available on the internet.

If CefSharp.BrowserSubProcess.exe is crashing and you can reproduce the crash on your development machine 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");

Getting a crash report from a customer's computer

See Crash Reporting section above for using Crashpad.

Older versions Check the AppData\Local\CrashDumps folder for CefSharp.BrowserSubProcess.exe dumps. To properly analyze a crash and obtain a symbolized stack trace you will need to load debugging symbols (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. (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 (debugger breakpoint)

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.

VS Debug Unmanaged Exceptions

Javascript Debugging

The Chromium DevTools are available for debugging Javascript, you can load DevTools programatically using the chromiumWebBrowser.ShowDevTools() method (there is a corresponding chromiumWebBrowser.CloseDevTools() method also). Make sure to add using CefSharp; to your usings statements.

Make sure you call this after the browser has been initialized.

using CefSharp;

//**OffScreen**
browser.BrowserInitialized += (sender, args) =>
{
    browser.ShowDevTools();
};

using CefSharp;

//**WinForms**
browser.IsBrowserInitializedChanged += (sender, args) =>
{
    browser.ShowDevTools();
};

//**WinForms (alternative)**
// If you see the DevTools window flickering 
// it's likely vying for focus with your form
// open DevTools on your UI Thread.
using CefSharp;

browser.IsBrowserInitializedChanged += (sender, args) =>
{
    var browser = (ChromiumWebBrowser)sender;

    browser.BeginInvoke((Action)delegate
    {
	browser.ShowDevTools();
    });
};

using CefSharp;
//**WPF**
browser.IsBrowserInitializedChanged += (sender, args) =>
{
    if ((bool)args.NewValue)
    {
        browser.ShowDevTools();
    }
};

If you are new to DevTools check out the official Chrome guide at https://developers.google.com/web/tools/chrome-devtools/#beginners

JavaScript Memory Debugging

Still having problems?

Ask on Gitter Chat - Make sure you provide as much detail as possible.

Clone this wiki locally