ILMerge alternative with embedded resources

We use ILMerge to merge a lot of assemblies to a single one for simpler deployment. The result is not compatible with Mono and has issues with WPF.

“… ILMerge works only on Windows-based platforms. It does not yet support Rotor or Mono … ILMerge is not able to merge WPF assemblies.”
ILMerge – Microsoft Research

On the ILMerge site there is a link to what they call “A Great Alternative to using ILMerge”: CLR via C#, Third Edition. The idea is to add all referenced assemblies as embedded resources and load them when they are needed. Here are my tips how to apply this to your project.

First I added all referenced assemblies my WPF application had. To keep things organized I added them to a folder called Resources. Next select all assemblies under Resources in the Solution Explorer and select “Embedded Resource” for the Build Action in the Properties window. This made my program around 10Mb in size after compilation.

In the constructor of the App.xaml.cs class add the AssemblyResolve eventhandler:

public App() : base()
{
    AppDomain.CurrentDomain.AssemblyResolve += (s, a) =>
    {
        var name = new System.Reflection.AssemblyName(a.Name).Name;
        var resourceName = string.Format("YOUR_NAMESPACE_HERE.Resources.{0}.dll", name);
        using (var stream = System.Reflection.Assembly.GetExecutingAssembly()
                                                      .GetManifestResourceStream(resourceName))
        {
            if (stream != null)
            {
                var assemblyData = new Byte[stream.Length];
                stream.Read(assemblyData, 0, assemblyData.Length);
                return System.Reflection.Assembly.Load(assemblyData);
            }
            else return null;
        }
    };
}

Notice the YOUR_NAMESPACE_HERE and the Resources after that. The assemblies are in the Resources folder and that will be part of the name of the embedded resource.

To be able to debug missing assemblies in the startup of your application, register an DispatcherUnhandledException handler and start a Debugger from there:

void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
    // Debugger will break on the line below
    System.Diagnostics.Debugger.Launch();
    // inspect the e.Exception
}

This will present you with an Just-In-Time Debugger dialog when an exception occurs and you can find out what happend.

Otherwise the application just crashes and you’ll see “FileNotFoundException” in the event viewer.

About erictummers

My work as a recruited developer changes almost every month. I like challenges and sharing the solutions with others. On my blog I’ll mostly post about my work, but expect an occasional home project, productivity tip and tooling review.
This entry was posted in Development and tagged , , , , , , , , . Bookmark the permalink.

3 Responses to ILMerge alternative with embedded resources

  1. Pingback: ILMerge alternative with embedded resources for class library | Erictummers's Blog

  2. Hi,

    I’m developing a WPF app that makes use of another assembly, which is created as a second project in the same Visual Studio solution. Is there any way to embed this assembly into the WPF app while still keeping the reference to the project, not the project’s build output?

    • erictummers says:

      Hello Dirk.
      The reference stays to the project (or compiled assembly). You need to add the compiled assembly of the referenced project as an embedded resource to you WPF app. When the WPF app runs it will not find the referenced project and fire the resolve event, which will load the assembly from the embedded resources.
      Greetz Eric

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s