12

In Common Language Runtime (CLR) Microsoft page, it says that both .Net Framework 4 and 4.5 uses the CLR version 4.

However in this page (.NET Framework Versions and Dependencies) it writes '.Net Framework version 4.5 Included an updated version of CLR 4'

Also writes:

'An executable that targets the .NET Framework 4.5.1 will be blocked from running on a computer that only has the .NET Framework 4.5 installed, and the user will be prompted to install the .NET Framework 4.5.1. In addition, .NET Framework 4.5.1 assemblies should not be called from a .NET Framework 4.5 app.'

QUESTION: If all Net Framework version 4 and 4.5 and 4.5.1 runs the managed code on the same CLR version that is 4, why I cannot run an executable that targeted .Net framework 4.5 on a machine that has only .Net 4.0 installed?

(Do not the compilers produce an IL that is for CLR version 4 in the end regardless you targeted .NET framework 4 or 4.5 or 4.5.1?)

Community
  • 1
  • 1
pencilCake
  • 45,443
  • 73
  • 211
  • 346

2 Answers2

18

Yes, the CLR version is the same, still v4.0.30319. What broke in a highly backwards-breaking way were the .NET Framework class libraries. Changes that were driven by integrating support for WinRT (Store apps) into the framework. Several types were moved from one assembly to another, the most visible ones are ExtensionAttribute and ICommand. The need for small .NET implementations on mobile devices was instrumental. System.Core and PresentationFramework are not small.

That's rather a big deal, the assembly that a type is declared in is part of the type identity of a .NET type. Or to put it another way, a .NET type that has the same namespace name and type name is never compatible with a type with the same full name that came from another assembly.

That this was possible at all was due to innovations that started in .NET 4.0. Starting with the [TypeForwardedTo] attribute which is what is used to move a type. And the specially crafted reference assemblies in c:\program files\reference assemblies. Special in that they only contain metadata and are not a direct match with the actual assemblies installed in the GAC that your program will use at runtime.

This does go wrong sometimes in a very hard to diagnose ways, induced by using the wrong reference assemblies. Unfortunately Microsoft kept the traditional reference assemblies in c:\windows\microsoft.net\framework around. Projects that use them fail in a pretty miserable way.

So this just can't work, a program that targets .NET 4.5 will look in the wrong 4.0 GAC assemblies for types like ExtensionAttribute and ICommand. And fail with a utterly undiagnosable TypeLoadException. Accordingly, the [TargetFramework] attribute is checked first to fail the attempt to run the program as early as possible.

Hans Passant
  • 873,011
  • 131
  • 1,552
  • 2,371
  • 2
    So, basically that is because particular types in FCL were moved to different assemblies. That means if I target .NET 4.5 and create a console app. And try to run it on a platform that has .NET 4.0 installed, based on the metadata of the compiled IL, CLR will look at referenced assemblies to use those particular types whereas they will be in some other assemblies. Did I get it correct? – pencilCake Mar 13 '14 at 13:18
  • 1
    Roughly. .NET 4.0 is smart enough to tell you that you need to install 4.5 and ask you to do it for you. [This answer](http://stackoverflow.com/a/10033128/17034) shows you what that looks like. – Hans Passant Mar 13 '14 at 13:48
  • 1
    And so, with ripples and waves and swells, we return inevitably to dll hell. – George Jun 27 '14 at 15:14
1

By Microsoft,

Every assembly, whether static or dynamic, contains a collection of data that describes how the elements in the assembly relate to each other. The assembly manifest contains this assembly metadata. Assembly Manifest. This manifest has information about the build CLR of that executable and while executing the exe/dll .net CLR tries to find out the same CLR version. See the image, Build by v 3.5 Build by v 3.5 and Build by 4.0 Build by 4.0.

Rohit Prakash
  • 1,851
  • 1
  • 12
  • 23