How do I use ILMerge with .NET 4.5 in AfterBuild?

Christian Fredh picture Christian Fredh · Jan 3, 2013 · Viewed 16.2k times · Source

We want to upgrade our solution with several projects to .NET 4.5. We already use Visual Studio 2012. We use ILMerge to merge the assemblies to a single EXE.

Our current .csproj file for the main project look like this:

<Target Name="AfterBuild" Condition=" '$(Configuration)' == 'Release' ">
    <CreateItem Include="@(ReferenceCopyLocalPaths)" Condition="'%(Extension)'=='.dll'">
        <Output ItemName="AssembliesToMerge" TaskParameter="Include" />
    </CreateItem>
    <PropertyGroup>
        <ReferenceAssemblies>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0</ReferenceAssemblies>
    </PropertyGroup>
    <Message Importance="high" Text="Executing ILMerge...with target platform from $(ReferenceAssemblies)" />
    <Exec Command="&quot;$(SolutionDir)LIB\ILMerge.exe&quot; /out:@(MainAssembly) /internalize /targetplatform:v4,&quot;$(ReferenceAssemblies)&quot; &quot;@(IntermediateAssembly)&quot; @(AssembliesToMerge->'&quot;%(FullPath)&quot;', ' ')" />
    <Delete Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
</Target>

How should this look for .NET 4.5?

I've read here that there are some issues using ILMerge with .NET 4.5.

Answer

Christian Fredh picture Christian Fredh · Jan 4, 2013

I can't find any good documentation on this, but as suggested by Matt Wrocks blog post and another question about ILMerge, I first tried to use the same Reference Assemblies path as for .NET 4.

This seemed to work at first, before re-targeting our NuGet packages to .NET 4.5. (Specifically Microsoft.AspNet.WebApi.Client which adds a reference to the new .NET 4.5 assembly System.Net.Http.WebRequest which before was included in the NuGet package.)

After updating reference assemblies path to .NET 4.5 it worked:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5

<Target Name="AfterBuild" Condition=" '$(Configuration)' == 'Release' ">
    <CreateItem Include="@(ReferenceCopyLocalPaths)" Condition="'%(Extension)'=='.dll'">
        <Output ItemName="AssembliesToMerge" TaskParameter="Include" />
    </CreateItem>
    <PropertyGroup>
        <ReferenceAssemblies>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5</ReferenceAssemblies>
    </PropertyGroup>
    <Message Importance="high" Text="Executing ILMerge...with target platform from $(ReferenceAssemblies)" />
    <Exec Command="&quot;$(SolutionDir)LIB\ILMerge.exe&quot; /out:@(MainAssembly) /internalize /targetplatform:v4,&quot;$(ReferenceAssemblies)&quot; &quot;@(IntermediateAssembly)&quot; @(AssembliesToMerge->'&quot;%(FullPath)&quot;', ' ')" />
    <Delete Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
</Target>

In most cases a path to .NET 4 assemblies would also work, but when referencing new assemblies in .NET 4.5, the path need to be updated.

Note that in the example ILMerge.exe is downloaded to a folder in the solution directory called LIB.