WPF: How to combine multiple assemblies into a single exe

At work, I am currently working on a small WPF app that we want to keep as a simple standalone exe. However, it has dependencies on several third-party assemblies: SharpZipLib, Unity, ServiceLocator, etc.

Microsoft has handy tool called ILMerge that merges multiple .NET assemblies into a single dll or exe. Unfortunately, it doesn’t support WPF applications, because of the way XAML is compiled.

Instead, you can use another approach — include all your referenced third-party assemblies as embedded resources of the exe:

public partial class App : Application
    private void OnStartup(object sender, StartupEventArgs e)
        AppDomain.CurrentDomain.AssemblyResolve += 
            new ResolveEventHandler(ResolveAssembly);

        // proceed starting app...

    static Assembly ResolveAssembly(object sender, ResolveEventArgs args)
        Assembly parentAssembly = Assembly.GetExecutingAssembly();

        var name = args.Name.Substring(0, args.Name.IndexOf(',')) + ".dll";
        var resourceName = parentAssembly.GetManifestResourceNames()
            .First(s => s.EndsWith(name));

        using (Stream stream = parentAssembly.GetManifestResourceStream(resourceName))
            byte[] block = new byte[stream.Length];
            stream.Read(block, 0, block.Length);
            return Assembly.Load(block);

Whenever .NET can’t find a referenced assembly, it will call our code and we can provide an Assembly instance ourselves. Note this code expects a sane DLL-naming convention :)

Update: Dan Chambers just tweeted about an improved and expanded version of this approach that automatically embeds referenced assemblies, and adds the assembly resolve hook at an earlier point in the app startup process.

11 thoughts on “WPF: How to combine multiple assemblies into a single exe

  1. Hi Richard,

    cool idea and it is working for me if I Add the following code at the beginning of the Load Resources handler:

    if((bool)TryFindResource(args.Name) == true) {
    return FindResource(args.Name) as Assembly;
    But if I reference a style in App.xaml which is defined in a component loaded it is not wrking. because the OnStartup Event is fired after the Resources in the App.xaml are resolved… ???

    Do you have any suggestions?

    Nice greetings, Markus

  2. Markus: OnStartup may be too late in the WPF application lifecycle. Try binding the event in the App constructor instead?

  3. Hi, thanks a lot for that one! I am not sure, but when the same assembly demanded from different places, isn’t the resource being read several times? If yes, simple caching is way to go.

    Anyway thanks for a cool idea ;-)

  4. Hi..

    I want to get the path of the .dll file used in one of my wpf application..
    I mean the Debug folder path of that .dll being created in some other application……..
    plz help me……..

  5. Hi Richard,
    I followed your steps but unfortunately can’t get this to work. I’m new to programming so don’t understand the background to most of this but I’ve added your code to App.xaml.cs and added the DLL to the Project as Embedded Resource. Everything compiles fine and the program runs ok when the DLL is in the same folder as the EXE. However, if I remove the DLL from the folder, the program will crash when it calls a function from the DLL. Any advise on what I can do to trouble shoot this?


Comments are closed.