I've been extremely frustrated trying to deploy a C#/WPF application I've created that has some references to 3rd party DLLs. I created a folder in the project, called lib
, where I placed all of these DLLs. In VS2012, I added the references by browsing to that folder, and selecting all the DLLs. Copy Local
is set to true
for all. Everything is fine when I build and run, but when I choose publish, and create a OneClick Installer, things aren't so smooth. During the publish wizard, I set it to install from disk, and set it to never check for updates. I take that folder, place it on a flash drive, plug it into another PC, run the setup, and it throws an Exception. I believe I know what is happening, but I cannot figure out how to package this in order to deploy it correctly.
One of my DLLs is a C# wrapper to a DLL that is designed for a C++ project. We'll say, Application
requires DLL1
and DLL1
requires DLL2
. DLL2
cannot be added as a reference in the project because is not a .NET
DLL. DLL1
requires DLL2
to be in the same folder in order to pick it up. I'm using CefSharp which wraps the Chromium Embedded Framework.
I've tried placing the required DLLs for CefSharp.dll in the publish/Application Files
directory, but it did not work. I noticed that all of the DLLs that are there from VS2012 have a .deploy
extension on them, I even went and added that extension on to see if it was scanning for that to pick up, but it did not work either. This is my first time doing development and deployment for a Windows application and all of the tutorials on MSDN or blog posts I've read do not seem to cover this case, and I do not see any other options in the deployment manager to handle these types of cases.
If it helps, the Exception Code that is thrown is: CLR20r3
When I catch and display Exception, all of the info I am provided basically says CefSharp.dll or one of it's dependencies cannot be loaded
. Which I've gotten before when DLL2
was not in the same folder as DLL1
.
Can anyone provide help on how to deploy from VS2012 with a situation like this?
Thanks in advance!
Edit: Info Update
I was attempting to push a debug build version to a test machine without Visual Studio installed. When building for CefSharp
or any other C++ Runtime DLL
, it will look for all of the Debug versions of the DLL
which are usually the same name, but with the letter 'd' added to the end. As mentioned below, the Debug version of the C++ Runtime is not redistributable. Not that you can't manually add those DLLs
to your project and set them as Copy Always
, but that's kind of a hack job. I started a new project from scratch, added all Release versions of the DLLs, built, and everything was fine.
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).
$(SolutionDir)packages\CefSharp.Wpf.1.25.7\cef
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.
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.
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.
Now if you publish your app, it should copy over all of the required files and folders.