Deploying WPF Application with 3rd Party DLLs

I've been tearing my hair out trying to fix this very problem this morning and eventually found the solution. It seems you already know which DLLs etc. you need for CefSharp to work but I thought I would run through this in case anyone else is having the same problem. I have a C# WPF application and I'm using CefSharp as the web view. I'm using CefSharp v1 because I need the JavaScript -> C# bridge they provide which isn't yet implemented in v3. Here are the rough steps I went through in setting up the project (I'm using VS2013 but this will probably work in VS2012).

Installing CefSharp

  • Install CefSharp.Wpf through NuGet (I'm using v1.25.7)
  • That should put the relevant files in $(SolutionDir)packages\CefSharp.Wpf.1.25.7\cef

Configuring Build

  • To get the CefSharp DLLs to copy to our build folders, right-click on your project, select Properties -> Build Events and enter the following in the "Post-build event command line":

    xcopy "$(SolutionDir)packages\CefSharp.Wpf.1.25.7\cef*" "$(TargetDir)" /s /y /i

  • That should now copy all of the required DLLs from the cef folder as well as the devtools_resources.pak file and the locales folder plus its contents. I require them in my project as I need the chromium dev tools.

  • Double-check your project references contain CefSharp and CefSharp.Wpf. That should have been taken care of by NuGet.

Taking care of Visual C++ 2012 Runtime Files

  • I didn't want the user to have to download the whole Visual C++ 2012 Runtime Files as part of the deployment so through Visual Studio, add the folder Lib\Microsoft.VC110.CRT and add the 3 DLLs (msvcp110.dll, msvcr110.dll, vccorlib110.dll) from the following folder on your machine to the folder you just created in your project:

    C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\redist\x86\Microsoft.VC110.CRT

  • Select the 3 DLL files in Visual Studio, right-click -> properties. Make sure Build Action is set to "None" and Copy to Output Directory is set to "Do not copy". Now you need to add another post-build event to make sure these are copied properly (i.e. copied to the root so they sit alongside the CEF dlls and your project exe) for debug.

  • Right-click on your project, select Properties -> Build Events and enter the following in the "Post-build event command line" just after your other xcopy command for CEF:

    xcopy "$(ProjectDir)Lib\Microsoft.VC110.CRT*.*" "$(TargetDir)" /s /y /i

At this point, everything should be building. To publish the app with ClickOnce, I need it to push all of the CEF DLLs out as well as ensuring the files/folders required for chromium dev tools are present. If you don't need the dev tools or all of the DLLs then you can tweak this accordingly.

Ensuring CEF and C++ runtime files are deployed with ClickOnce

  • Right click your project in Visual Studio and select "unload project".

  • Right click and select to edit the csproj file.

  • Before the closing </Project> tag add this

    <ItemGroup>
       <Content Include="$(SolutionDir)packages\CefSharp.Wpf.1.25.7\cef\**\*">
         <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
         <Visible>false</Visible>
      </Content>
    </ItemGroup>
    
    <ItemGroup>
       <Content Include="$(ProjectDir)Lib\Microsoft.VC110.CRT\**\*">
          <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
          <Visible>false</Visible>
      </Content>
    </ItemGroup>
    
  • That will add everything from the cef folder into the project and make sure the C++ binaries are copied to the root of the project on deployment. In my case for CEF, I'm using the \**\* syntax at the end of the Include and %(RecursiveDir) to ensure all of the files are copied as well as the locales folder with its contents and structure preserved. Having set <Visible>false</Visible> you won't see the items in the solution explorer.

Relax

Now if you publish your app, it should copy over all of the required files and folders.


Since you already tried manually adding the suspect dll and it still does not work, the next thing I would do is run fusion and see what it really is complaining about, in other words what exactly is the dependency that can not be loaded. Here is a good tutorial on how to hunt down these types of errors:

Back to Basics: Using Fusion Log Viewer to Debug Obscure Loader Errors


Maybe you can work it out from the https://github.com/Code52/DownmarkerWPF sources?

They have at least a working ClickOnce installer for their app embedding CefSharp. I know because that's the way it got installed on my machine!

update just saw in comments that it's the VC Redist that you say you are missing then Distributing the Visual C++ Runtime Libraries (MSVCRT) seems relevant.

Also I seem to remember something vaguely about that for "VCRedist reasons" you are not supposed to distribute debug versions of your application. Can't you just switch from a Debug to a Release version? With this I think you can either bundle the needed VCRedist files as suggested in the CefSharp FAQ or add VCRedist as a prerequisite in your installer. DownmarkerWPF does it with their WIX installer setup which you can find on a branch in their GitHub repo. Something similar is AFAIK possible with the VStudio bundled installer if that's what you use.


You could try this which solved a similar issue for me:

Add the DLL's that are not .NET libraries to the solution as files:

Right click project > Add > Existing Item

Then set their build action to Content and "Copy to output directory" to "Copy Always".

That way the libraries will be included in the output directory.