Click here to Skip to main content
15,886,362 members
Articles / Desktop Programming / WPF

Compiling Multiple Projects into a Single EXE File in WPF

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
30 Nov 2011CPOL3 min read 20K   4   1
How to compile multiple projects into a single EXE file in WPF

A long time ago, I wrote a simple application using WPF (I will write about this utility in my next post) that I recently dug up from the lost archives and I wanted to use in my every day life (at work and at home).

I realized that this small application was made up of 3 projects, thus creating one EXE file and two extra DLL files. Since I want to pack it light, and I truly see no reason to carry around 3 files that are all under 1 MB, I looked for a way to compile all of these under one file.

After looking on the internet a little bit, I found a simple solution, which probably isn't the best way to do it, but it works good enough for me...

First, in my main project, I created a folder called Assemblies, and put the other compiled DLLs into this folder manually. Then, I defined these DLLs' Build Action to be 'Embedded Resource' (this is found in the Properties window of every file in your project - image attached). This will cause the DLLs to be compiled as resources embedded into the output EXE file.

And now that the DLLs are in the EXE file, we can delete the DLLs in our output folder and just run our EXE file, right? Wrong! The CLR will still look for these files in the folder (and also in the GAC) and when it doesn't find them, it won't know what to do.

So all we need to do actually is just tell the compiler where to look when it doesn't find the files in the original location. This is done by overriding the method AssemblyResolve in our current AppDomain object like this:

C#
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
    String resourceName = "MyProject.Assemblies." + 
      new AssemblyName(args.Name).Name + ".dll";
    using (var stream = 
      Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
    {
        if (stream == null) ;

        byte[] assemblyData = new byte[stream.Length];
        stream.Read(assemblyData, 0, assemblyData.Length);
        return Assembly.Load(assemblyData);
    }
};

What we did here is just retrieve all the embedded resources and find the specific assembly the CLR was looking for.

Now, after compiling your project, you can delete the other DLL files in your output folder and the EXE file will work on its own.

While thinking of this solution, I didn't like the idea of having to copy the assemblies after every change into the 'Assemblies' folder I created, and then compiling again... but after thinking about it for a while, I think it's not that bad in my case if I consider the circumstances - I'm talking about a very small solution, only 3 projects, and all I need this packing into one file is to move it around. I also don't believe I will be working on it that much more, so this means I just need to do this once. If it was a current project at work or even for fun, I wouldn't go with this option, and I would've found a better way around this...

An extra note: While running the application for the first time, it immediately crashed. I opened it in debug mode (which actually meant I needed to put a Thread.Sleep() in the initialization and then attach to the process through VS since I wanted to delete the DLL files before debugging). I realized that the application was looking for an assembly called XmlSerializers that I never created. I don't know exactly why, but it turns out that this was automatically generated while compiling. No worries though, this can be taken care of. Just go to the project properties > Build > Output > Generate serialization assembly = Off.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Israel Israel
Started programming e-commerce sites with PHP & MySQL at the age of 14. Worked for me well for about 5 years.

Transfered to C# & asp.net, while serving in the IDF.
Worked on the 'Core Performance' Team at ShopYourWay.com (Sears Israel)
Currently working at Logz.io

Check out my blog!
or my twitter

Comments and Discussions

 
GeneralVery nice. thanks Pin
itsho27-Oct-15 1:37
itsho27-Oct-15 1:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.