Search code examples
c#vb.netwebbrowser-controlcefsharpexcel-dna

How to use Cefsharp browser control in ExcelDNA add-in?


I creating excel add-In with ExcelDNA that contains Cefsharp browser in Custom task pane. When I run add-In, I'll get an error about:

Could not load file or assembly "CefSharp, Version=65.0.0.0, Culture=neutral, PublicKeyToken=40c4b6fc221f4138" or one of its dependencies. The specified module could not be found.

How can I fix that?

Creating user control that contains ChromiumWebBrowser:

        [ComVisible(true)]
        public class MyBrowser : UserControl
        {
            ChromiumWebBrowser browser = new ChromiumWebBrowser("www.google.com");
            browser.Dock = DockStyle.Fill;
            this.Controls.Add(browser);
        }

Code for creating custom task pane:

        private static void CreateCTP()
        {
            ctp = CustomTaskPaneFactory.CreateCustomTaskPane(typeof(MyBrowser), 
                            "My Custom Task Pane");
            //Setting ctp params...
            ctp.Visible = true; 
        }

NOTE:

  • All dependencies/references connected and files (unmanaged resources) added into bin/Debug.
  • Add-In works normaly (if ChromiumWebBrowser not using).

Solution

  • This is a known issue with CefSharp... It is not compatible with non-default AppDomains. You can see more details in the issue "Multiple AppDomains error "Cannot pass a GCHandle across AppDomains"

    Excel-DNA creates a custom/non-default AppDomain for each add-in, and CefSharp doesn't like that. Someone tried to fix CefSharp a while ago, but unfortunately the pull-request was not accepted/merged and the problem still persists. If you're brave enough, you can download that pull-request and have your own version of CefSharp, with that fix applied.

    A workaround to use CefSharp as-is with Excel-DNA is to run it in separate process, in a default AppDomain. Examples of how to do it here and here.

    You can also read more about this in this discussion: "CefSharp and ExcelDNA".

    Of course, given this is a CefSharp-specific problem, another alternative is to use something else instead, like CefGlue or ChromiumFx, for example.