Clone wiki

ChromiumFX / Project

Project Setup and Description



Setting up a working project environment

  1. Clone the repo and update to top revision.
  2. Read cef/README.txt for the required CEF version.
  3. Download the required CEF binary packages for Windows 32-bit and/or 64-bit from the CEF download page or https://cefbuilds.com/ or http://opensource.spotify.com/cefbuilds/index.html.
  4. Extract Resources into cef/Resources, 32-bit Release into cef/Release and/or 64-bit Release into cef/Release64.
  5. Copy cef/Resources/icudtl.dat into cef/Release/ and/or cef/Release64.

Done. Try to compile ChromiumFX.sln. If it compiles, and the test application runs fine, then you have a working project environment. ChromiumFX.sln will compile into target directories Build/Debug and Build/Release.

VS Community 2015 is used for this project, but it should work with any version of the VS IDE that supports .NET 4.0. With some minor changes, it should compile for 3.5 as well.

Application Layout

ChromiumFX supports AnyCPU, x86 and x64 applications. While ChromiumFX itself is platform agnostic, the underlying native binaries are always platform specific. You can distribute your application with the following default layouts:

AnyCPU Application

For distributions that will run in 32-bit mode on 32-bit platforms and 64-bit mode on 64-bit platforms, compile your application for AnyCPU. The downside is that you will have to distribute CEF binaries for both platforms, effectively doubling the size of CEF files in your application.

Application/ /* your application folder */
    Application.exe /* your application executable compiled for AnyCPU */
    ChromiumFX.dll
    [ChromiumWebBrowser.dll] /* optional, only for ChromiumWebBrowser control */
    libcfx.dll
    libcfx64.dll
    cef/
        libcef.dll /* 32-bit libcef version */
        (...) /* other required and optional CEF binaries and resource files */
        locales/
            en-US.pak
            (...) /* other locales (optional) */
    cef64/
        libcef.dll /* 64-bit libcef version */
        (...) /* other required and optional CEF binaries and resource files */
        locales/
            en-US.pak
            (...) /* other locales (optional) */

This can be reduced in size by providing only one directory of CEF resources and locales for both 32-bit and 64-bit CEF and point to that directory in the CfxSettings.ResourcesDirPath and CfxSettings.LocalesDirPath settings. The icudtl.dat file has to be kept next to libcef.dll in both cef directories though.

x86 Application

For distributions that will run in 32-bit mode on both 32-bit and 64-bit platforms, compile your application for x86.

Application/ /* your application folder */
    Application.exe /* your application executable compiled for x86 */
    ChromiumFX.dll
    [ChromiumWebBrowser.dll] /* optional, only for ChromiumWebBrowser control */
    libcfx.dll
    cef/
        libcef.dll /* 32-bit libcef version */
        (...) /* other required and optional CEF binaries and resource files */
        locales/
            en-US.pak
            (...) /* other locales (optional) */

x64 Application

For distributions that will run in 64-bit mode on 64-bit platforms and not run at all on 32-bit platforms, compile your application for x64.

Application/ /* your application folder */
    Application.exe /* your application executable compiled for x64 */
    ChromiumFX.dll
    [ChromiumWebBrowser.dll] /* optional, only for ChromiumWebBrowser control */
    libcfx64.dll
    cef64/ /* or alternatively cef/ */
        libcef.dll /* 64-bit libcef version */
        (...) /* other required and optional CEF binaries and resource files */
        locales/
            en-US.pak
            (...) /* other locales (optional) */

Notes

  • In all three layouts, libcfx.dll and/or libcfx64.dll can also be kept in the cef/ and/or cef64/ directory.

  • The following alternative layout works for x86 and x64 applications without additional settings:

Application/ /* your application folder */
    Application.exe /* your application executable (x86 or x64) */
    ChromiumFX.dll
    [ChromiumWebBrowser.dll] /* optional, only for ChromiumWebBrowser control */
    libcfx.dll /* or libcfx64.dll */
    libcef.dll
    (...) /* other required and optional CEF binaries and resource files */
    locales/
        en-US.pak
        (...) /* other locales (optional) */
  • For different layouts, your application can use a combination of CfxRuntime.LibCefDirPath, CfxRuntime.LibCfxDirPath, CfxSettings.ResourcesDirPath and CfxSettings.LocalesDirPath. For required and optional CEF binaries and resource files, see cef/README.txt.

  • Important: Unless you specify a specific path for secondary processes in CfxSettings.BrowserSubprocessPath, you have to disable the "Enable the Visual Studio hosting process" checkbox in Project Properties->Debug. Otherwise, the program won't be able to spawn secondary processes and you get a blank browser window.

  • Do not include .lib files (cef_sandbox.lib and libcef.lib). They are not required and bloat the size of your distribution (especially cef_sandbox.lib).

Project Description

ChromiumFX consists of 2 solutions and 5 projects:

ChromiumFX.sln

libcfx.vcxproj contains the native layer

This is pure native code dealing with subclassing and refcounting and provides a clean interface between CEF and ChromiumFX with opaque structs. It also allows for optimized pinvoke by providing the necessary interface.

The native layer is pure native code (no CLI). This allows for static linking with the C runtime library, avoiding dependencies from Visual C++ runtime dlls. Avoiding those dependencies really matters because it avoids redistribution of the VC++ runtime which is a pain. So all you have to distribute are libcfx.dll, ChromiumFX.dll (and ChromiumWebBrowser.dll if you want to use the Winforms control) along with the required CEF binaries. For required and optional CEF binaries, read cef/README.txt.

ChromiumFX.csproj contains the managed layers

The pinvoke layer is built on top of the native layer, takes care of optimized marshaling and deals exclusively with blittable types provided by the native layer. for instance, if you pass strings into CEF, like in CfxBrowser.LoadUrl(string), no string copying occurs: The managed string is pinned, and it's pinned pointer is passed into the native layer and wrapped into a cef_string_t struct.

The public layer wraps it all up in .NET style classes prefixed with "Cfx": CfxApp, CfxBrowser, CfxBrowserHost, etc. Handler classes, used by CEF for callouts from the framework into the embedding application, are designed as containers of managed events in the standard .NET event style: Event(sender, EventArgs).

The remote layer provides a transparent RPC bridge between the browser process and the render process. Due to the multi-process architecture of Chromium, CEF applications which deal with advanced features like DOM and V8 access have to split their logic between the browser process and the render process. ChromiumFX implements a fourth layer, the remote layer, providing a complete API of .NET style classes for transparently accessing the render process from within the browser process: CfrApp, CfrBrowser, CfrFrame, etc. Application logic can deal with CfrDomDocument, CfrV8Context, CfrV8Handler and so on directly in the browser process, ChromiumFX will marshal application calls and framework callbacks to and from the render process using IPC. All Application logic can be kept in the browser process.

ChromiumWebBrowser.csproj

Built upon ChromiumFX, ChromiumWebBrowser is an easy to use Windows Forms control. Using the remote layer, it allows you to attach javascript objects, properties and functions with C# callback into the browser process, access to the DOM from within the browser process, local resources for custom URLs and so on.

CfxTestApplication.csproj

This is an executable project where tests are done. Don't expect it to be an extensive test environment, it is not. I use it to test the code paths I need in the application for which I developed ChromiumFX in the first place.

As a matter of fact, only a subset of the generated code gets actually exercised in the test application or my own embedding application. But since almost all of the code is generated, in theory, if it works in one place, it should work in other places too.

Well ok, this one calls for a quote from Einstein: "In theory, theory and practice are the same. In practice, they are not." - so if you run into issues, you are welcome to use the issue tracker :)

CfxGenerator.sln

CfxGenerator.csproj

This is the application that generates the generated files. It was originally written in VB and later converted into C#. It is meant to be run from within the Visual Studio IDE in debug mode. It allows me to upgrade to newer CEF versions in less than one hour of work. Over time, I hope to clean it up in order to make it more useable for others.

You don't need to run CfxGenerator if you just want to built ChromiumFX because the generated files are in the repo. As a matter of fact, if you run it unmodified and without changing the header files in cef/include, then it will not change a single line of generated code.

This is roughly the work flow for a CEF update:

  1. Download the CEF package.
  2. Delete from cef/include all files except include/internal/cef_linux.h and include/internal/cef_types_linux.h.
  3. Extract all header files from include, include/base, include/capi and include/internal into the cef/ directory. Extract LICENSE.txt and README.txt into the cef/ directory.
  4. Extract Resources into cef/Resources, 32-bit Release into cef/Release and/or 64-bit Release into cef/Release64. Copy cef/Resources/icudtl.dat into cef/Release/ and/or cef/Release64.
  5. Run CfxGenerator from the IDE in debug mode. Watch the output.
  6. If CfxGenerator hits a breakpoint or assert or produces any output, make the necessary changes and repeat last step. No breakpoint, no assert and no output is good.
  7. Build ChromiumFX.sln
  8. If the build fails, make the necessary changes to CfxGenerator and goto 5.
  9. Run ChromiumFX.sln from the IDE in debug mode.
  10. If the test run fails, make the necessary changes to CfxGenerator and goto 5.
  11. Seems to work. Test the new version in your own app.

The main repo will be kept synchronized with the CEF release branch corresponding to the chromium stable channel. CfxGenerator should also be able to generate correct files for most older versions and new releases. Sometimes a new release of the CEF API introduces changes the generator can't handle. In that case, the generator has to be fixed. Feel free to use the issue tracker if that happens.

Updated