Single exe applications
On many occasions I find myself writing small tools to meet a very specific requirement. These tools are usually console applications or simple forms applications. For portability I like applications of this type to be a standalone exe.
The problem is that, in the interest “Not Invented Here”, I find myself wanting to reference third party libraries. At the very least I will reference an IOC (like AutoFac or Windsor) and a logging library (like nlog or log4net). So now I have three files to manage (or six if you count pdbs)
ILMerge as an option
For a period I used ILMerge to merge libraries. However there are some issues with ILMerge and WPF.
From Mike Barnett’s blog http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx
> ILMerge is not able to merge WPF assemblies. They contain resources with encoded assembly identities. ILMerge is unable to deserialize the resources, modify the assembly identities, and then re-serialize them. Sorry!
Use Embedded resources
I then stumbled across Jeffrey Richter's suggestion of using embedded resources as a method of merging assemblies http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx This seems like the ideal solution however it has the drawback of copying a small chunk of code every time I want to employ this method. The reason is the code for the AssemblyResolve event is responsible for loading third party assemblies and hence cannot exist in a third party assembly.
Enter IL Weaving
So to make this AssemblyResolve code re-usable I started inserting it with ILWeaving. The difficult part of this was working out the location, in IL, for the application entry point. I figured wiring up some code that executes on module load (a module initializer) would be easier. I found several sites that stated module initializers were not possible in .net. And then I found the truth on Einar Egilsson's blog http://tech.einaregilsson.com/2009/12/16/module-initializers-in-csharp/ Module initializers are possible in .net, just not in c#.
So the end result is Costura http://code.google.com/p/costura/ This provides the following for ease of use and portability
- An MSBuild task
- A Visual Studio package so there is a UI for tweaking the MSBuild task http://visualstudiogallery.msdn.microsoft.com/70c0e54d-07de-4ff3-a62f-aac9c31e8c39
Have a play and let me know what you think.
No new comments are allowed on this post.