Click here to Skip to main content
13,297,878 members (46,084 online)
Click here to Skip to main content
Add your own
alternative version


29 bookmarked
Posted 1 Dec 2005

Post build step static linking tool for C#, using ILMerge

, 1 Dec 2005
Rate this:
Please Sign up or sign in to vote.
Post build step static linking tool for C#, using ILMerge.


So there I was, wanting to release an application of mine, but I didn’t want to release all the assemblies that my application used. Why? Well, that would be exporting some functionality that this particular app didn’t use, and even though it was dotfuscated, it just felt wrong.

It turns out that .NET, and even .NET 2.0, despite people asking for it, does not support static linking. For those not sure what that is – static linking is when you don’t compile to a DLL, you compile to a .lib, and then the whole thing gets linked together into one .exe file.

There are many arguments as to the pros & cons of static linking, and I am not going to get into that here – suffice to say that I wanted to static link – which is good enough for me.

So – off to Google I go, and I find that Microsoft has a tool called ILMerge, which takes a plethora of parameters. What ILMerge does is de-compile .NET assemblies and then build them all into one primary assembly. Yes, it does .NET 2.0 as well.

You can also use ILMerge within your own applications as it exposes an interface, so you can just reference it (obviously, you can only do this in VS 2005, as prior to that, you cannot use .exe files as a reference – you can however get around this in 2003 if you so wish – search CodeProject – it has been done in here!).

What HTMerge (Hollingside Technologies Merge) does is make it so simple that I just have a post build step as:

htmerge "$(TargetDir)

The “ before the $ is to ensure that directory paths with spaces in are parsed correctly. This does assume that HTMerge is on the path. Given that parameter as a post build step, all assemblies that are part of your application are merged into one .exe file, which is stored in a subdirectory called merged beneath the debug/release directory.

As it stands, this code only works properly when building a .exe type project, but the concept stands.

Hope someone finds this useful!

The code

using System;
using System.Text;
using System.Collections;

namespace HTMerge
    class Program
        static void Main(string[] args)
                String strDir = "";
                if (args.Length != 1)
                    Console.WriteLine("Usage: HTMerge directoryName");
                    strDir = args[0];

                String[] exeFiles = System.IO.Directory.GetFiles(strDir, "*.exe");
                String[] dllFiles = System.IO.Directory.GetFiles(strDir, "*.dll");

                ArrayList ar = new ArrayList();

                Boolean bAdded = false;

                //there might be more than 1 exe file, 
                //we go for the first one that isn't the vshost exe
                foreach (String strExe in exeFiles)
                    if (!strExe.Contains("vshost"))
                        bAdded = true;

                if (!bAdded)
                    Console.WriteLine("Error: No exe could be found");
                    //I know multiple returns are bad…

                bAdded = false;

                foreach (String strDLL in dllFiles)
                    bAdded = true;

                //no point merging if nothing to merge with!
                if (!bAdded)
                    Console.WriteLine("Error: No DLLs could be found");
                    //I know multiple returns are bad…

                //You will need to add a reference to ILMerge.exe from Microsoft
                ILMerging.ILMerge myMerge = new ILMerging.ILMerge();

                String[] files = (String[])ar.ToArray(typeof(string));

                String strTargetDir = strDir + "\\Merged";


                //Here we get the first file name 
                //(which was the .exe file) and use that
                // as the output
                String strOutputFile = System.IO.Path.GetFileName(files[0]);

                myMerge.OutputFile = strTargetDir + "\\" + strOutputFile;

            catch (Exception ex)
                Console.WriteLine(String.Format("Error :{0}",ex.Message));



This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Web Developer
United Kingdom United Kingdom
I have been developing software since I first got hold of a ZX80 age 10. After a few years with BBC Basic and 6502 assembler (I used to write articles for PCW and Acorn User) I then discovered Pascal with Objects and quickly moved to C++ where I spent 15happy years before finding the joys of c#.

After discovering the wonders of working for myself I founded Hollingside Technologies ( We offer c# / c++ / Delphi / SQL and also management consultancy. As well as the consultancy work we have run a number of successful C# and Object Oriented Programming training courses. Past bespoke software that we have written includes mobile software (pocket PC) that integrates with MS Exchange via GPRS for a sales team; remote hardware monitoring software; scanning and image recognition software for passport control and a heap of other stuff.

When not being a geek I play guitar in a semi-successful rock band( and am a competitive fencer.

Other spare time is spent walking my dogs and riding my motorbike.

After all that? Give me a good beer and a splatter movie!

You may also be interested in...


Comments and Discussions

Bugexited with code 9009 Pin
saurabhsavaliya23-Feb-12 22:02
membersaurabhsavaliya23-Feb-12 22:02 
GeneralRe: exited with code 9009 Pin
manicguitarist23-Feb-12 23:39
membermanicguitarist23-Feb-12 23:39 
The 9009 error code is a error code, not returned from the merging program.

It indicates that it can't find the folder specified. Try using "$(TargetDir) instead of a hardcoded path.
GeneralMy vote of 5 Pin
mungflesh9-Feb-11 5:53
membermungflesh9-Feb-11 5:53 
GeneralAssemblyResolver not called Pin
John Boehm15-Jan-09 4:37
memberJohn Boehm15-Jan-09 4:37 
GeneralModification for DLL as primary assembly... Pin
manicguitarist2-Sep-08 23:19
membermanicguitarist2-Sep-08 23:19 
GeneralModification to Handle a DLL as the Primary Assembly Pin
Strince2-Sep-08 13:56
memberStrince2-Sep-08 13:56 
GeneralReferencing ILMerge.exe Pin
janreimers19-Feb-07 6:28
memberjanreimers19-Feb-07 6:28 
Generalanother way Pin
Vasian Cepa1-Dec-05 23:50
memberVasian Cepa1-Dec-05 23:50 
GeneralRe: another way Pin
margiex30-Dec-05 1:22
membermargiex30-Dec-05 1:22 
GeneralRe: another way Pin
Vasian Cepa30-Dec-05 3:28
memberVasian Cepa30-Dec-05 3:28 
GeneralRe: another way Pin
Douba29-Jun-06 1:39
memberDouba29-Jun-06 1:39 

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.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.171207.1 | Last Updated 1 Dec 2005
Article Copyright 2005 by manicguitarist
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid