«

»

Mar 06 2013

Could not load type ‘System.Runtime.CompilerServices. ExtensionAttribute’ from assembly mscorlib when using ILMerge

Works On My Machine

Works On My Machine

I ran into a pretty horrible problem with ILMerge this week when attempting to build and deploy a windows service I’d been working on. While the merged executable & subsequently created MSI worked fine on my own machine, it gave the following rather nasty problem when run on a colleagues machine.

Error!

Could not load type ‘System.Runtime.CompilerServices.ExtensionAttribute’ from assembly mscorlib

It turns out that between .NET 4.0 & .NET 4.5; this attribute was moved from System.Core.dll to mscorlib.dll. While that sounds like a rather nasty breaking change in a framework version that is supposed to be 100% compatible, a [TypeForwardedTo] attribute is supposed to make this difference unobservable.

Unfortunately things breakwhen ILMerge is used to merge several assemblies into one. When I merge my .NET 4.0 app, with some other assemblies on the machine with .NET 4.5 installed, it sets the targetplatform for ILMerge to .NET 4.0. This in turn looks into C:\windows\Microsoft.NET\Framework\v4.0.30319 to find the relevant DLLs. But since .NET 4.5 is an in place upgrade, these have all been updated with their .NET 4.5 counter parts.

Breaking Changes

“Every well intended change has at least one failure mode that nobody thought of”

You need to specific that ILMerge should use the older .NET 4.0 reference assemblies which are still available in C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0. (or program files x86) if your on a 64-bit box). There’s more info on the stackoverflow question where I finally found a solution and in a linked blog post by Matt Wrock.

http://stackoverflow.com/questions/13748055/could-not-load-type-system-runtime-compilerservices-extensionattribute-from-a

and

http://www.mattwrock.com/post/2012/02/29/What-you-should-know-about-running-ILMerge-on-Net-45-Beta-assemblies-targeting-Net-40.aspx

To override this behavior you need to specify this target platform directory as part of your ILMerge command. e.g.

"C:\Path\To\ILMerge.exe"
    /out:"$(TargetDir)OutputExecutable.exe"
    /target:exe
    /targetplatform:"v4,C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"
      "$(TargetDir)InputExecutable.exe"
      "$(TargetDir)A.dll"
      "$(TargetDir)B.dll"
I had previously been using the ILMerge.MSBuild.Tasks tool from nuget but unfortunately, this library doesn’t currently support specifying the TargetPlatform. There’s an unactioned open item on their issue tracker in google code.
~EoinC

About the author

Eoin

Husband, son, brother, I grok technologiy. I write code. I take photos. I teach & practice Krav Maga. I play football. I eat good-food. I drink nice-wine.

Permanent link to this article: http://trycatch.me/could-not-load-type-system-runtime-compilerservices-extensionattribute-from-assembly-mscorlib-when-using-ilmerge/

Leave a Reply