Compartilhar via


Hack the Build: Use ILMerge and MSBuild to Combine Multiple Assemblies into One

Jomo Fisher--Over the last few years I've been coding mostly in C#--before that, my day-to-day work was done in C++. I don't miss much about C++, but one of the things that I do miss is the ability to link many .LIB files into a single DLL or EXE

I've known that it was possible to do this in .NET (with LINK.EXE or ILMERGE.EXE) but there is no built-ine support in VS2005 for doing this.

This weekend, I decide to see what it would take to plug ILMERGE into the regular C# build system. It's pretty simple to get basic support.

(1) Download and install ILMerge MSI: https://www.microsoft.com/downloads/details.aspx?FamilyID=22914587-b4ad-4eae-87cf-b14ae6a939b0&displaylang=en

(2) Save the this file to C:\Program Files\msbuild\Ilmerge.CSharp.targets

(3) In VS2005, right-click on the projectin solution explorer and select "Unload Project"

(4) Right-click again and pick 'Edit MyApp.csproj'

(5) Replace the <Import> line with <Import Project="$(MSBuildExtensionsPath)\Ilmerge.CSharp.targets" /> and save.

(6) Right-click again on the project in solution explorer and select "Load Project"

(7) Build.

Now, the project you modified will automatically have all referenced assemblies merged-in. Only the assemblies marked "Copy Local" will be merged so system assemblies and GAC assemblies won't be merged by default.

You only need to modify the projects you would like to have merging. In other words, you can have mixed merged and unmerged projects in the same solution.

This posting is provided "AS IS" with no warranties, and confers no rights.

Comments

  • Anonymous
    March 05, 2006
    Готовое решение. Выполняем по пунктам 1,2,3, и... Проект в Visual Studio сам соб

  • Anonymous
    March 23, 2006
    I finished creating a code generator for Dice, and I turned the thing into a custom build task for MSBuild...

  • Anonymous
    April 24, 2006
    The comment has been removed

  • Anonymous
    April 04, 2007
    okay i'm starting to think that by stumbling onto your blog i've made my way into an alternative reality where magical things are possible. this is just full on. it's one thing to describe the rough concepts behind how such a thing might be achieved... but to go ahead and produce a (supposedly) working implementation... that's truly magical. okay, my brain hurts from the very thought of it.  and it's all reminiscent of a joel spolsky article entitled 'please sir, may i have a linker?' which you ought to read if you haven't, as you've just shown how to solve what he said was a major shortcoming of .net. cheers lb

  • Anonymous
    June 12, 2007
    Hi. After several days trying to change the csproj to do the ilmerge after build, i found this post. Thx. So, during my tests, although i could run the command in the cmd window, i always got errors like, "exited with code 1" or 123 or 9099 (or 9009 i dont remember). Using this patch to csproj, i got the "exited with code 3". Could you help me? thx in advance

  • Anonymous
    October 05, 2007
    PingBack from http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspx

  • Anonymous
    October 08, 2007
    I really like the new LINQ to XML direct language support in VB9 . However, while it's cool, I'm not

  • Anonymous
    August 22, 2008
    Great! But... In a project i use a DI-framework (Autofac) and MSTest. When i build the test lib, which references both my .exe and autofac.dll, it fails because it finds autofac classes both in the merged .exe and the .dll... If i remove the Autofac reference in the Test project it builds but the intellisens, and recognition of Autofac classes, is gone.

  • Anonymous
    November 14, 2008
    The comment has been removed

  • Anonymous
    November 20, 2008
    Well I managed to solve this satisfactorily by moving the code from the include file directly into the project file and being sure to place it before the post-build (signing) action. Seems to work great. Thanks again for the awesome post!

  • Anonymous
    November 24, 2008
    The custom target works well but the output file is no more signed (using a pfx file choose in the project properties). Is there anything I missed to make it working ?

  • Anonymous
    June 12, 2009
    The comment has been removed

  • Anonymous
    March 16, 2010
    Great Article man, I have one question, my app has increased as for memory usage, I'm kind of sure It's because the .exe file is loading a lot more content. Could you reply to to me regarding this little problem.

  • Anonymous
    May 05, 2010
    It would be nice if you could explain why steps 3 to 6 are necessary and what they really do. The problem is that I'm using C# express 2008, and don't have 'Unload Project' menu from Solution window, so I can't follow your steps. Are those step only necessary for an existing project? How about the new project? Why the step 5 is necessary? why can't you put that in the script?  

  • Anonymous
    July 19, 2011
    Past this in the post-build cahnge the file name of the DLL's. IF EXIST Merge GOTO MERGEDIR MKDIR Merge :MERGEDIR "C:Program FilesMicrosoftILMergeILmerge.exe" /target:library /out:MergeWSFClient.dll Microsoft.ApplicationBlocks.Data.dll WSFClient.dll