Ultimately the easiest thing to do is to exclude log4net completely from the ilmerge process and maintain it as a dependent assembly.
So after much torture here's the "not-so-obvious" solution..
The excludes were not required after all, the real answer is to use the /lib:[path]
switch in ilmerge.
I updated the AfterBuild
target to remove the excludes from the /internalize
switch. Next I added the /lib
switch to pass in the location of the log4net dll as a dependent reference. It looks like this:
<Target Name="AfterBuild">
<CreateItem Include="@(ReferenceCopyLocalPaths)" Condition="'%(Extension)'=='.dll'">
<Output ItemName="AssembliesToMerge" TaskParameter="Include" />
</CreateItem>
<Message Text="MERGING: @(AssembliesToMerge->'%(Filename)')" Importance="High" />
<Exec Command=""$(ProgramFiles)\Microsoft\Ilmerge\Ilmerge.exe" /lib:..\packages\log4net.2.0.0\lib\net35-full\ /targetplatform:v2 /log /internalize /keyfile:$(AssemblyOriginatorKeyFile) /out:@(MainAssembly) "@(IntermediateAssembly)" @(AssembliesToMerge->'"%(FullPath)"', ' ')" />
<Delete Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
</Target>
In addition, I've added another target to restrict the list of assemblies included in the merge by adding a unique <ILMerge />
element to the references located in my .csproj file
<Target Name="AfterResolveReferences">
<Message Text="Filtering out ILMerge assemblies from ReferenceCopyLocalPaths..." Importance="High" />
<ItemGroup>
<ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.ILMerge)'=='false'" />
</ItemGroup>
</Target>
Thus the reference elements were listed like so to accommodate:
...
<Reference Include="Ionic.Zip">
<HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath>
<ILMerge>True</ILMerge>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.0\lib\net35-full\log4net.dll</HintPath>
<ILMerge>False</ILMerge>
...
There's probably a better (programmatic) alternative for explicitly adding ILMerge=False values to the /lib
switch but, in my case it is sufficient due to there being only one excluded item. Otherwise you may need to add additional paths manually.
Credit for the 'AfterResolveReferences' technique I've listed goes to http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspx
Hopefully this helps someone!