5
votes

We're having the seemingly common error

Could not load type 'System.Runtime.CompilerServices.ExtensionAttribute' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

in a project that needs to be compiled against .Net 4.0 but is built on a build server running Windows Server 2012 (with .Net 4.5). The project is a web application that gets deployed to a web server running 2003, where installing .Net 4.5 isn't an option. There it runs against "classic" .Net 4.0

From similar questions, we're trying command-line options to MSBuild:

/property:FrameworkPathOverride="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"

We also tried various combinations of

/property:ReferencePath="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"
/property:NoStdLib=true
/property:NoCompilerStandardLib=true

The reference assemblies (including the .dll files) are in fact installed in that place on the build server. But when we deploy the website and visit the home page, we get that error. (Interestingly, on a page reload, the error disappears, and the site operates normally.) What are the MSBuild parameters necessary to compile against the .Net 4.0 assemblies?

Update I turned on ludicrous-level logging on MSBuild, and I see that apparently it is building against the .Net 4.0 reference assemblies:

Resolved file path is "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll

and I didn't see any mention of assemblies outside that folder or the build server's working directory. So it appears to compile properly, but when deployed on the web server, it throws the exception.

As to the exception going away on a page reload, I wonder if that's related to the markup pre-compile step. We're running aspnet_compile on the build server. Maybe if there's an exception coming from a generated assembly, the web server will re-compile it. And the recompiled assembly is fine, because it was created with true .Net 4.0.

1
Are you using ILMerge?Hans Passant
We're not using ILMerge.Carl Raymond
Rename C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll on that build server and do a clean build. You'll find the project that uses the wrong reference assemblies.Hans Passant
Good idea! We're trying to figure how to do that on Windows 2012. It's fighting us the whole way.Carl Raymond
It took us a bit to figure out how to rename it. Now I have a lot of NuGet errors that I'm digging into.Carl Raymond

1 Answers

3
votes

Well the answer turned out to be borderline embarrassing. After we confirmed from detailed MSBuild output that it was in fact building the website project against the right reference assemblies, we realized that there are several in-house NuGet packages in the project that had been built against .Net 4.5. One of them was chock full of extension methods, which is what causes the exception. Rebuilding them against .Net 4.0 fixed the problem.

Which brings up an interesting issue. If a 3rd-party NuGet package is compiled for 4.0 but using 4.5 references, we'd be in the same situation, but not able to fix it. So the lesson for package publishers is to ensure your 4.0 version is compiled against the reference assemblies.