Sunday, November 13, 2011

Assemblies Merging With Post-build Event

ILMerge is a useful utility to merge multiple .NET assemblies into a single assembly. By using the "Post-build" event command line, we can automate the merging process when building our projects.

There is a better method by using MSBuild. Please refer Assemblies Merging With ILMerge and MSBuild.

For my projects, I use a ILMergeHelper batch file to run the ILMerge process. By using this script, all files inside the bin output are copied over to a sub folder "ReleaseMerged". All merging process are done within this sub folder, as such, nothing in the bin output folder will be affected.

Syntax:
ILMergeHelper.bat <targetDir> <targetFileName> <solutionName> <inputAssemblies> [cleanAssemblies]
Arguments:
  • targetDir - The merged output directory.
  • targetFileName - The merged output file name.
  • solutionName - The project solution name.
  • inputAssemblies - The assemblies to be merged. Must enclose with double-quotes, separate each assembly name with a space within the quotes. Supports wildcards.
  • cleanAssemblies - Optional. The files to be deleted after the merging completed. If not set, will be same as inputAssemblies. Must enclose with double-quotes, separate each assembly name with a space within the quotes. Supports wildcards.
Note: Please see example below.

Setup ILMerge and ILMergeHelper (only set once):

1. Download and install the ILMerge utility.
  • Note: You may copy the "ILMerge.exe" and put it into any custom folder, as long as you change to the correct path in your post-build command line.

2. Create a batch file named as "ILMergeHelper.bat" with the following contents:
@ECHO OFF

REM #############################################################################################################
REM #### ILMergeHelper.bat
REM #### A utility to perform ILMerge using the Post-build event from the Visual Studio project
REM #### Author: Weizh Chang
REM ####
REM #### Usage: ILMergeHelper.bat <targetDir> <targetFileName> <solutionName> <inputAssemblies> [cleanAssemblies]
REM ####
REM #### Example (set in Post-build event): 
REM #### ILMergeHelper.bat $(TargetDir) $(TargetFileName) $(SolutionName) "support*.dll" "support*.dll"
REM #############################################################################################################

@ECHO ON

REM #### Set variables from arguments

SET targetDir=%1
SET targetFileName=%2
SET solutionName=%3

SET inputAssemblies=%4
SET inputAssemblies=%inputAssemblies:"=%

SET cleanAssemblies=%5
IF (%cleanAssemblies%)==() SET cleanAssemblies="%inputAssemblies%"
SET cleanAssemblies=%cleanAssemblies:"=%

SET mergedDir=%targetDir%..\ReleaseMerged\

REM #### Set the merged file name
SET mergedFileName=%targetFileName%

REM #### Remove existing merged directory
IF EXIST %mergedDir% RD /S /Q %mergedDir%

REM #### Copy all contents from the build target folder to the merged folder
XCOPY %targetDir%* %mergedDir% /i /E /Y /Q
CD /D "%mergedDir%"

REM #### Perform ILMerge
%~dp0ILMerge /lib:%mergedDir% /wildcards /allowDup /ndebug /out:%mergedDir%%mergedFileName% %targetFileName% %inputAssemblies%

REM #### Delete all assemblies that have been merged
DEL /Q %cleanAssemblies%
3. Put this file into the same folder as ILMerge.exe (e.g. C:\Program Files\Microsoft\ILMerge\).

4. Open your project's Properties > Build Events > Post-build event, and enter the ILMergeHelper command. For example:
"C:\Program Files\Microsoft\ILMerge\ILMergeHelper.bat" $(TargetDir) $(TargetFileName) $(SolutionName) "support*.dll MySql*.dll" "support*.* MySql*.* test.xml"
Note:
  • The above example merges all assemblies named support*.dll and MySql*.dll, then delete all files with names support*.*, MySql*.* and test.xml.
  • This example uses macros $(TargetDir) and $(TargetFileName) as the merged output directory and file name. You may change them to other values you preferred.

5. Build the project. The merged assembly is created inside the "ReleaseMerged" folder.


Additional Resources:
Assemblies Merging With ILMerge and MSBuild


If you find this post helpful, would you buy me a coffee?


2 comments:

  1. Well done! But a couple of comments here:
    I had to include /targetplatform:v4,"C:\Windows\Microsoft.NET\Framework64\v4.0.30319" at the end of line 42:
    %~dp0ILMerge /lib:%mergedDir% /wildcards /allowDup /ndebug /out:%mergedDir%%mergedFileName% %targetFileName% %inputAssemblies%

    Also instead of just pasting that into the Post build event, I had to use 8.3 notations, in my case, just changes Program Files to Progra~2, because I have windows 8 64 bits.

    Thanks a lot.

    ReplyDelete
    Replies
    1. You're welcome, and thanks for sharing your solution.
      It's strange to me you need to set to 8.3 notations, but anyway glad that it works.

      Delete