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 removedAnonymous
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 lbAnonymous
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 advanceAnonymous
October 05, 2007
PingBack from http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspxAnonymous
October 08, 2007
I really like the new LINQ to XML direct language support in VB9 . However, while it's cool, I'm notAnonymous
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 removedAnonymous
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 removedAnonymous
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