This document describes the ILMerge utility which merges multiple .NET assemblies into a single assembly. However, some .NET assemblies may not be able to be merged because they may contain features such as unmanaged code. I would highly recommend using peverify (the .NET Framework SDK tool) on the output of ILMerge to guarantee that the output is verifiable and will load in the .NET runtime.
ILMerge is packaged as a console application. But all of its functionality is also accessible programmatically. Note that Visual Studio does allow one to add an executable as a reference, so you can write a client that uses ILMerge as a library.
ILMerge takes a set of input assemblies and merges them into one target assembly. The first assembly in the list of input assemblies is the primary assembly. When the primary assembly is an executable, then the target assembly is created as an executable with the same entry point as the primary assembly. Also, if the primary assembly has a strong name, and a .snk file is provided, then the target assembly is re-signed with the specified key so that it also has a strong name.
Note that anything that depended upon any of the names of the input assemblies, e.g., configuration files, must be updated to refer instead to the name of the target assembly.
Any Win32 Resources in the primary assembly are copied over into the target assembly.
There are many options that control the behavior of ILMerge. These are described in the next section
ILMerge Commands
Command Line Usage
The full command line for ILMerge is:ilmerge [/lib:directory]* [/log[:filename]] [/keyfile:filename [/delaysign]] [/internalize[:filename]]
[/t[arget]:(library|exe|winexe)] [/closed] [/ndebug] [/ver:version] [/copyattrs [/allowMultiple]]
[/xmldocs] [/attr:filename] ([/targetplatform:<version>[,<platformdir>]]|v1|v1.1|v2|v4)
[/useFullPublicKeyForReferences] [/zeroPeKind] [/wildcards] [/allowDup[:typename]]*
[/allowDuplicateResources] [/union] [/align:n]
/out:filename <primary assembly> [<other assemblies>...]
All options that take arguments can use either :
or =
as a separator. Options can be in any order, but all of the options must precede the list of input assemblies. AllowDuplicateType
public void AllowDuplicateType(string typeName);
[/allowDup[:typeName]]*
AllowMultipleAssemblyLevelAttributes
public bool AllowMultipleAssemblyLevelAttributes { get; set; }
false
Command line option: /allowMultiple
AllowWildCards
public bool AllowWildCards { get; set; }
false
Command line option: /wildcards
AllowZeroPeKind
public bool AllowZeroPeKind { get; set; }
false
Command line option: /zeroPeKind
AttributeFile
public string AttributeFile { get; set; }
null
Command line option: /attr:filename
Closed
public bool Closed { get; set; }
false
Command line option: /closed
CopyAttributes
public bool CopyAttributes { get; set; }
false
Command line option: /copyattrs
DebugInfo
public bool DebugInfo { get; set; }
true
Command line option: /ndebug
DelaySign
public bool DelaySign { get; set; }
/keyfile
option (Section 2.13).
Default: false
ExcludeFile
public string ExcludeFile { get; set; }
/internalize[:excludeFile]
FileAlignment
public int FileAlignment { get; set; }
512
Command line option: /align:n
Internalize
public bool Internalize { get; set; }
false
Command line option: /internalize[:excludeFile]
public string KeyFile { get; set; }
When this is set before calling Merge, it specifies the path and filename to a .snk file. The target assembly will be signed with its contents and will then have a strong name. It can be used with the DelaySign property (Section 2.9) to have the target assembly delay signed. This can be done even if the primary assembly was fully signed.
Default: null
Command line option: /keyfile:filename
public bool Log { get; set; }
When this is set before calling Merge, then log messages are written. It is used in conjunction with the LogFile property. If Log is true, but LogFile is null, then log messages are written to Console.Out. To specify this behavior on the command line, the option "/log" can be given without a log file.
Default: false
Command line option: /log[:logfile]
public string LogFile { get; set; }
When this is set before calling Merge, it indicates the path and filename that log messages are written to. If Log is true, but LogFile is null, then log messages are written to Console.Out.
Default: null
Command line option: /log[:logfile]
public void Merge();
Once all desired options are set, this method performs the actual merging.
public string OutputFile { get; set; }
This must be set before calling Merge. It specifies the path and filename that the target assembly will be written to.
Default: null
Command line option: /out:filename
public bool PublicKeyTokens { get; set; }
This must be set before calling Merge. It indicates whether external assembly references in the manifest of the target assembly will use full public keys (false) or public key tokens (true).
Default: true
Command line option: /useFullPublicKeyForReferences
public void SetInputAssemblies(string[] assems);
When used programmatically, each element of the array should contain the path and filename of an input assembly. The first element of the array is considered to be the primary assembly.
public void SetSearchDirectories(string[] dirs);
If specified, this sets the directories to be used to search for input assemblies. When used programmatically, each element of the array should contain a directory name. When specified on the command line, use a separate "/lib" option for each directory.
Command line option: /lib:directory
public void SetTargetPlatform(string platform, string dir);
This method sets the .NET Framework for the target assembly to be the one specified by platform. Valid strings for the first argument are v1
, v1.1
, v2
, and v4
;. The v
is case insensitive and is also optional. This way ILMerge can be used to "cross-compile", i.e., it can run in one version of the framework and generate the target assembly so it will run under a different assembly. The second argument is the directory in which mscorlib.dll
is to be found.
Command line option: /targetplatform:version,platformdirectory
public bool StrongNameLost { get; }
Once merging is complete, this property is true if and only if the primary assembly had a strong name, but the target assembly does not. This can occur when an .snk file is not specified, or if something goes wrong trying to read its contents.
public ILMerge.Kind { get; set; }
This controls whether the target assembly is created as a library, a console application or as a Windows application. When it is not specified, then the target assembly will be the same kind as that of the primary assembly. (In that case, the file extensions found on the specified target assembly and the primary assembly must match.) When it is specified, then the file extension of the target assembly must match the specification.
The possible values are ILMerge.Kind.{Dll, Exe, WinExe}
Default: ILMerge.Kind.SameAsPrimaryAssembly
Command line option: /target:(library|exe|winexe)
public bool { get; set; }
When this is true, then types with the same name are all merged into a single type in the target assembly. The single type is the union of all of the individual types in the input assemblies: it contains all of the members from each of the corresponding types in the input assemblies. It cannot be specified at the same time as /allowDup
.
Default: false
Command line option: /union
public System.Version Version { get; set; }
When this has a non-null value, then the target assembly will be given its value as the version number of the assembly. When specified on the command line, the version is read in as a string and should look like "6.2.1.3" (but without the quote marks). The version must be a valid assembly version as defined by the attribute AssemblyVersion in the System.Reflection namespace.
Default: null
Command line option: /ver:version
public bool XmlDocumentation { get; set; }
This property controls whether XML documentation files are merged to produce an XML documentation file for the target assembly.
Default: false
Command line option: /xmldocs





