I know I'm not the first person to ask this question on Stack Overflow and I'm sure I won't be the last. But, after spending hours researching how to do this and then physically trying to do it, I'm near ready to give up.
I have a .NET Framework 4, C#, WinForms application that builds to an executable. I rely on many many many dlls. The dlls fall into multiple categories.
- Libraries I have written with no dependencies of their own
- Libraries I have written with dependencies on other libraries I've written
- Libraries I have written with dependencies on third party dlls
- Third party stand alone dlls
- Third party dlls with their own dependencies on other dlls
So after I compile my application I have a directory with an executable and approximately 15 dlls.
I want to pack all the dlls into a single executable so that I can simply distribute a single executable.
I know that IlMerge is the typically suggested application to use for this, but I'm curious if there is something easier to use that is more intuitive and works accross both WinForms and WPF.
ILMerge only combines pure (not mixed-mode) CLR assemblies. It works by extracting all of the CIL modules and then relinking them into a single new assembly. Assembly resources are also recombined.
ILMerge cannot merge native executable code. lame_enc.dll is a native DLL file and does not contain any CIL modules, that's why you can't combine it.
If you want to pack your application into a single executable a workaround is to include lame_enc.dll as an assembly resource, then save lame_enc.dll to disk in a temp folder perhaps, and add the folder it was saved in to your application's PATH, so your [DllImport] runtime linker will be able to access it.
The problem here is that ILMerge only can merge .Net assemblies. Your file lame_enc.dll isn't a .Net assembly but a standard Windows dll and therefore can't be loaded by ILMerge.
To get around this you could embed lame_enc.dll in your assembly and then extract it when needed in your application. Check out this article for more info on that.
http://weblogs.asp.net/ralfw/archive/2007/02/04/single-assembly-deployment-of-managed-and-unmanaged-code.aspx
In the end, I went an entirely different direction.
I decided to use the Costura Visual Studio Extensions located here.
These extensions use a combination of two methods
What's nice here is that you simply install the extensions into Visual Studio. After doing that, for any project where you want to pack your DLLs into a single executable, simply select the project, click Project on the menu bar, Costura, Configure, and then OK. It will ask you to reload the project - click yes. Now whenever you build the project it will create just a single executable (or DLL if you are doing it on a library). Couldn't be more easy.
To address your exact issue, verify that the file
C:\Release\lame_enc.dll
exists and that it is in fact a .NET file. ILMerge can only merge .NET assemblies.Now if you are only worried about distribution of your application, you may consider creating an installer to install all of the binaries, and not worry about merging them using ILMerge.
Another alternative to using ILMerge is to embed the binaries in an assembly as desribed here.