Contact   •   Products   •   Search

Rick Strahl's Web Log

Wind, waves, code and everything in between...
ASP.NET • C# • HTML5 • JavaScript • AngularJs

.NET 4.5 is an in-place replacement for .NET 4.0


With the betas for .NET 4.5 and Visual Studio 11 and Windows 8 shipping many people will be installing .NET 4.5 and hacking away on it. There are a number of great enhancements that are fairly transparent, but it's important to understand what .NET 4.5 actually is in terms of the CLR running on your machine.

When .NET 4.5 is installed it effectively replaces .NET 4.0 on the machine. .NET 4.0 gets overwritten by a new version of .NET 4.5 which - according to Microsoft - is supposed to be 100% backwards compatible. While 100% backwards compatible sounds great, we all know that 100% is a hard number to hit, and even the aforementioned blog post at the Microsoft site acknowledges this. But there's so much more than backwards compatibility that makes this awkward at best and confusing at worst.

What does ‘Replacement’ mean?

When you install .NET 4.5 your .NET 4.0 assemblies in the \Windows\.NET Framework\V4.0.30319 are overwritten with a new set of assemblies. You end up with overwritten assemblies as well as a bunch of new ones (like the new System.Net.Http assemblies for example). The following screen shot demonstrates system.dll on my test machine (left) running .NET 4.5 on the right and my production laptop running stock .NET 4.0 (right):

VersionDifferences[8] 

Clearly they are different files with a difference in file sizes (interesting that the 4.5 version is actually smaller).

That’s not all. If you actually query the runtime version when .NET 4.5 is installed with with Environment.Version you still get:

4.0.30319

If you open the properties of System.dll assembly in .NET 4.5 you'll also see:

.NET VersionDialog

Notice that the file version is also left at 4.0.xxx.

There are differences in build numbers: .NET 4.0 shows 261 and the current .NET 4.5 beta build is 17379. I suppose you can use assume a build number greater than 17000 is .NET 4.5, but that's pretty hokey to say the least.

There’s no easy or obvious way to tell whether you are running on 4.0 or 4.5 – to the application they appear to be the same runtime version. And that is what Microsoft intends here. .NET 4.5 is intended as an in-place upgrade.

Compile to 4.5 run on 4.0 – not quite!

You can compile an application for .NET 4.5 and run it on the 4.0 runtime – that is until you hit a new feature that doesn’t exist on 4.0. At which point the app bombs at runtime. Say you write some code that is mostly .NET 4.0, but only has a few of the new features of .NET 4.5 like aync/await buried deep in the bowels of the application where it only fires occasionally. .NET will happily start your application and run everything 4.0 fine, until it hits that 4.5 code – and then crash unceremoniously at runtime. Oh joy!

You can .NET 4.0 applications on .NET 4.5 of course and that should work without much fanfare.

Version Detection

If you're building a .NET 4.5 application you do have some control over the runtime via YourApp.exe.config file options. Specifically you can specify that the app requires .NET 4.5 like this (thanks for Scott Hanselman pointing this out in the comments):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0"
                      sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

This works to ensure that the app will refuse to start on .NET 4.0 with an error on startup rather than waiting for something to blow up at runtime.

Likewise .NET 4.5 Web applications can use the targetFramework element on the <compilation> element:

<configuration>
  <system.web>
    <compilation debug="true"
                 strict="false"
                 explicit="true"
                 targetFramework="4.5" />
  </system.web>
</configuration>

This works fine for standalone applications and server, but it there's no solution for assemblies that are added to other projects. To a 4.0 project a .NET 4.5 assembly just looks like another 4.0 assembly.

For developers - especially component developers - this is also problematic since there's no built in way to determine whether you're running .NET 4.5. Environment.Version returns 4.0.

The following code block (dumped into the awsome LinqPad):

void Main()
{
    Environment.Version.ToString().Dump();
    Environment.Version.Build.Dump();
    Environment.Version.Revision.Dump();
    Environment.Version.Major.Dump();    
}

On .NET 4.0 it results in:

4.0.30319.269
30319
269
4

On .NET 4.5 it results in:

4.0.30319.17379
30319
17379
4

Pretty close, eh? Note however that the Revision number is high on .NET 4.5 - 17379 on the current build, while the .NET 4.0 revision number is 261. So if you really have to check specifically for .NET 4.5 you can use code like this:

// Define other methods and classes here
public static bool IsDotNet45()
{
    return Environment.Version.Major == 4 &&
           Environment.Version.Revision > 17000;
}

Others have commented (on Hanselman's post), that it's better to do feature detection for a new feature of .NET 4.5. The code Scott used uses a new class for .NET 4.5 plus some Reflection code to check for it:

public static bool IsNet45OrNewer()
{
    // Class "ReflectionContext" exists from .NET 4.5 onwards.
    return Type.GetType("System.Reflection.ReflectionContext", false) != null;
}

One advantage of this approach is that you're checking for a feature rather than a specific version, so in the future this code will continue to work so you effectively can future proof code.

Still it's pretty telling that we'll have to resort to this sort of chicanery just to figure out freaking version compatibility.

Different than .NET 3.0/3.5

Note that this in-place replacement is very different from the side by side installs of .NET 2.0 and 3.0/3.5 which all ran on the 2.0 version of the CLR. The two 3.x versions were basically library enhancements on top of the core .NET 2.0 runtime. Both versions ran under the .NET 2.0 runtime which wasn’t changed (other than for security patches and bug fixes) for the whole 3.x cycle. The 4.5 update instead completely replaces the .NET 4.0 runtime and leaves the actual version number set at v4.0.30319.

When you build a new project with Visual Studio 2011, you can still target .NET 4.0 or you can target .NET 4.5. But you are in effect referencing the same set of assemblies for both regardless which version you use. What's different is the compiler used to compile and link your code so compiling with .NET 4.0 gives you just the subset of the functionality that is available in .NET 4.0, but when you use the 4.5 compiler you get the full functionality of what’s actually available in the assemblies and extra libraries. It doesn’t look like you will be able to use Visual Studio 2010 to develop .NET 4.5 applications.

Good news – Bad news

Microsoft is trying hard to experiment with every possible permutation of releasing new versions of the .NET framework apparently. No two updates have been the same. Clearly updating to a full new version of .NET (ie. .NET 2.0, 4.0 and at some point 5.0 runtimes) has its own set of challenges, but doing an in-place update of the runtime and then not even providing a good way to tell which version is installed is pretty whacky even by Microsoft’s standards. Especially given that .NET 4.5 includes a fairly significant update with all the aysnc functionality baked into the runtime. Most of the IO APIs have been updated to support task based async operation which significantly affects many existing APIs.

To make things worse .NET 4.5 will be the initial version of .NET that ships with Windows 8 so it will be with us for a long time to come unless Microsoft finally decides to push .NET versions onto Windows machines as part of system upgrades (which currently doesn’t happen). This is the same story we had when Vista launched with .NET 3.0 which was a minor version that quickly was replaced by 3.5 which was more long lived and practical.

People had enough problems dealing with the confusing versioning of the 3.x versions which ran on .NET 2.0. I can’t count the amount support calls and questions I’ve fielded because people couldn’t find a .NET 3.5 entry in the IIS version dialog. The same is likely to happen with .NET 4.5. It’s all well and good when we know that .NET 4.5 is an in-place replacement, but administrators and IT folks not intimately familiar with .NET are unlikely to understand this nuance and end up thoroughly confused which version is installed.

It’s hard for me to see any upside to an in-place update and I haven’t really seen a good explanation of why this approach was decided on. Sure if the version stays the same existing assembly bindings don’t break so applications can stay running through an update. I suppose this is useful for some component vendors and strongly signed assemblies in corporate environments. But seriously, if you are going to throw .NET 4.5 into the mix, who won’t be recompiling all code and thoroughly test that code to work on .NET 4.5? A recompile requirement doesn’t seem that serious in light of a major version upgrade. 

Resources

Make Donation
Posted in .NET  


Feedback for this Post

 
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Steven Berkovitz March 13, 2012 @ 2:13pm
Try looking at the File Version (properties dialog), not the Assembly Version to see which version of the file it is..
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by @koty March 13, 2012 @ 4:54pm
thank you for your explanation. .NET 4.5 looks like .NET 4.0 sp1 isn't it ?
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Staffan March 14, 2012 @ 1:16am
I suppose they had the ambition to release a "3.0/3.5 release", but realized they wanted to add all those new Task-based API:s into existing assemblies, rather than adding lots of System.IO.Async assemblies which would hurt later on. With there being just additions (and bug fixes) an "upgrade install" probably made sense to Redmond. Not justifying, only speculating.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Lex Li March 14, 2012 @ 3:13am
Consider the old story of .NET 3.5 SP1, where lots of new features were added, they should this time name it as .NET 4 SP, instead of 4.5.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Mike March 14, 2012 @ 5:59am
Microsoft sucks at versioning, they just can't seem to wrap their heads around semver. Only Hanselman and Haacked seem to get it, which is reflected in NuGet and MVC. Recently the EF team got called out on it, and they seem to be in the process of getting their act together, recently it's simply been 4.2, 4.3 etc.

But .NET itself is a mess, let's hope they rebase at 5.0 and then get it right.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Vasu March 14, 2012 @ 7:16am
Can you elaborate how the IIS version dialog looks? There is no .NET 4.5 option in there? That would be very confusing is'nt it.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by mknopf March 14, 2012 @ 10:53am
Thanks for the heads up, we host hundreds of apps across more than 100 servers so this could have been a real issue for our Sys Admins if they weren't aware that it replaces the 4.0 assemblies
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Michael K. Campbell March 14, 2012 @ 10:54am
Rick,

As always a great post.

While this WILL cause all sorts of goofy problems and headaches for developers, the REAL problem here (as I see it) is that it delivers a huge NEGATIVE blow to the .NET Framework for the IT Pros and businesses (pointy-haired bosses) who will end up colliding with these 'stealth' versioning conflicts. They won't see this as an issue where Microsoft tried something new.

Instead, they'll see this as merely being a case where .NET apps are hard to support. So the next time developers want to use .NET for internal apps in companies where this was already a question of whether or not .NET made sense or not will see ADDITIONAL push-back from the folks that manage these apps.

That, and it's NOT like people didn't complain about everything you've listed here prior to them launching this silliness upon the world.

I complained about it more than 5 months ago here - where I also outlined how I'm worried about how much of a NEGATIVE sentiment this will create among businesses and IT pros who get bitten by the issues that this WILL cause:
http://www.devproconnections.com/article/net-framework/net-framework-45-versioning-faces-problems-141160

--Mike
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by James March 15, 2012 @ 9:26am
I would love to hear an explanation from Microsoft on this. Maybe Scott Guthrie can weigh in here on their reasoning.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by John March 23, 2012 @ 4:43am
>Clearly they are different files with a difference in file sizes (interesting that the 4.5 version is actually smaller).
I think is because they get rid of the old SSE optimization code. Now SSE2 instructions are a requirement for .Net 4.5. That's why people with old Athlon XP CPU's are suffering lots of application crashes and can't open Metro apps even if they have a 2Ghz CPU that meets the Windows 8 minimum requirements.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Olivier March 27, 2012 @ 12:45am
Suppose I have this code:

if (System.WhateverClass.FrameworkVersion.StartsWith("4.0")) Console.WriteLine("Hi 4.0");


This would break if the framework version was updated... I suppose that making sure one can't distinguish between 4.0 & 4.5 is part of the 100% compatibility goal!

Pun intended.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Rick Strahl March 27, 2012 @ 2:49am
@Olivier - LOL! Good one :-)
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Carl Franklin March 28, 2012 @ 3:06pm
I showed this to Scott Guthrie today. He's passing it around to try and get an official response from Microsoft.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Josh Einstein April 02, 2012 @ 6:55pm
With every new version of the .NET framework, I feel like Microsoft is taking Brad Abrams and Krzysztof Cwalina's vision of a consistent, predictable, and cohesive framework and making it so royally screwed up that they have no choice but to hit the reboot button every few years and come up with some crap like WinRT as if .NET was flawed all along.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Scott Hanselman April 03, 2012 @ 8:54pm
You might update the section on deploying .NET 4.5 apps on .NET 4. Both will not run if they use the default configurations. For examples, a WinForms/Console/WPF app will have:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>   
   <startup>         
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
   </startup>
</configuration>
And this will prompt the user to download .NET 4.5.

On ASP.NET, they'll have:

<configuration>
    <system.web>
        <compilation debug="true" strict="false" explicit="true" targetFramework="4.5" />
    </system.web>
</configuration>


And this will throw a YSOD on startup when run under .NET 4.0.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Rick Strahl April 03, 2012 @ 9:39pm
Thanks Scott. That should help and is the behavior I would expect to be correct. I think it's more important for desktop applications than server applications I think since those go into potentially many different environments.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Colin Bowern May 01, 2012 @ 6:24am
Not sure if you saw it but during one of the BUILD sessions (http://channel9.msdn.com/events/BUILD/BUILD2011/TOOL-834T I believe) they mentioned that the replacement was to drive some changes to the underlying CLR that they couldn't do with an additive release. Sounds like there is a big push to ensure compat which is why the product group is asking people to try the beta out.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Rick Strahl May 01, 2012 @ 2:17pm
@Colin - well to me the fact that I have to install 4.5 and wipe out 4.0 is actually the main reason I'm NOT trying it out. It's a totally intrusive install with no good way to undo short of uninstalling .NET 4.5 and 4.0 and reinstalling which in turn will break a lot of stuff that relies on .NET 4.0 - even if you immediately turn around and re-install .NET 4.5. For example, IIS apps revert to .NET 2.0 when you uninstall 4.0/4.5, and won't revert back to 4.0 when you reinstall .NET 4/5.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Mike May 17, 2012 @ 10:40am
To your point about being able to run .NET 4.0 applications on .NET 4.5 - I found at least one issue:

I was just playing around with a annoying behaviour with the WPF datagrid that was changed on the last release of the WFP Toolkit and made it into .NET 4.0: http://wpf.codeplex.com/workitem/13022

In .NET 4.5 the behaviour has been changed to not set the SelectedItem to null when the DataGrid is disabled (yeah!)

However, now when I create a WPF application targeting .NET "4.0" the behaviour will be different depending if .NET 4.5 or .NET 4.0 is installed on the client machine... yikes! Not really 100% backward compatible.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Peter May 31, 2012 @ 7:09am
Also TypeMock, a unittest framework we use seem to have the problem with the backward compatibility, chk http://forums.typemock.com/viewtopic.php?f=4&t=4716

After installing VS2011 beta my unittest fail to run, mesg: Failed to queue test run "": Unable to start the agent process. Uninstalling 4.5 en installing 4.0 fixes it for me. There is also an unpdate available for TypeMock but i could use that yet due to project constraints.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Warren August 08, 2012 @ 2:33am
Thanks Rick, that also explains why uninstalling .NET 4.5 also uninstalls .NET 4.0, that makes sense now (but didn't at the time).
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Alex August 16, 2012 @ 7:57am
This is a critical issue if you still have an XP user base, like I do. Bugs that existed in 4.0 and are fixed in 4.5 do not show up during debugging on my Windows 7 workstation, but do when my app is run on a customer's XP box. They are not given an option to upgrade because 4.5 is not supported and I cannot repro the issue (even when targeting 4.0) on my development machine.

This was extremely bad practice from Microsoft.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by 80s Rocker September 17, 2012 @ 2:51pm
I do agree that the version number is confusing (expecially if your write a lot of desktop applicaiton. But for web applications I think it is a little clearer. After install installing .Net 4.0, there is not option under .Net version to run you application under ".Net 4.5", the only option is ".Net 4.0". So in reality you are running your application under .Net 4.0, just it has been updated with new functionality. So in this case if the version number was set to 4.5 and there was an option for it in IIS, then that would even be more confusing (since the options would point to the same code base, so it would not matter which you chose). I am wondering if that is why they could not update the version number from 4.0 to 4.5.

Bottom line is, if .Net 4.5 is installed then you can run apps targetting .Net 4.0 & .Net 4.5 applications otherwise you can only run apps targeting .Net 4.0. As far as backward compatibility, IMO you should always plan on regression testing all applicaiton after installing any new version of the .Net runtime. This went for 3.0 and 3.5, becuase I am pretty sure that there were some updates to a few of the core library functions that were called by the new .Net 3.0/3.5 libraries so they would work correctly with the new functions. It was not a complete upgrade of the .Net 2.0 framework like 4,5 is, but there was still the possibility (even thouhg minimal risk) that the the core changes could have broken an applicaiton that used those functions.

Tha being said, I totally agree that MS blew it on this one and they should have released this as ".Net 5.0" and have it be a side-by-side install. The main reason I think this is that an in-place replacemment upgrade makes it a harder sell when involved in an enterprise. I a also wondering how this will affect hosting companies that support .Net 4.5 and how soon they will offer .Net 4.5 as an option. I know that where I work we will probably not update any of our exsitig servers to .Net 4.5, and we will have to wait for new servers to be built with .Net 4.5 installed from the start. That way we can regression test applicaions / web services as we migrate to the new web servers.

That is my 2 cents.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Hugh October 25, 2012 @ 7:08am
This is - I have to say - pretty ridiculous. From the moment .Net was spoken of we all heard how "DLL Hell" would be a thing of the past due to the (sound) versioning and signing capabilities of the platform.

As Rick says every new release of the framework has followed a different "policy" and (I think) is always accompanied by confusion and uncertainty even among hardened experienced tech people.

Adding a NEW version of .Net on a machine should have zero impact on existing applications on that machine - is this now too lofty a goal?

If the specific version and build numbers are abstruse (as they are) then Microsoft should have long ago created a utility "FrameworkInfo" that can list and shed light on EVERY version of .Net installed on a machine - this would help humans see what are .Net 4.5 and .Net 4.0 assemblies for example.

There are issues with all this - apart form the bewildering 4.5/4.0 mess there is also the fact that a) AppDomains often (always?) load TWO copies of every assembly and b) There are at least TWO physical copies of every .Net assembly on a machine (one in the GAC and the other in an ordinary folder - seen by VS when you use 'add reference').

It looks to me like DLL Hell is slowly making a return...

Hugh
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Duncan Smart October 04, 2013 @ 1:22am
If you're looking for a way to see if .NET 4.5 is installed from something simple like a batch file then querying for
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.5

seems to do the trick.

For example
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.5" 2>nul
if errorlevel 1 (
   echo .NET Framework 4.5 is NOT installed
) else (
   echo .NET Framework 4.5 is installed
)


Hope that helps.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Jamin Shanti December 19, 2013 @ 7:56am
Lazy Microsoft Developers.

This should be a new code branch. Got burnt on this. 4.5.1 patch destroyed 4.0 servers.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Bayta Darell February 12, 2014 @ 4:23pm
Hi Rick

Great post!, but when you say "You can .NET 4.0 applications on .NET 4.5 of course and that should work without much fanfare."

I'm not totally agree, because I have an application compiled with 4.0 framework and now for an incompatibility issue with IE11 following the microsoft suggestion I upgraded to 4.5 framework in order to solve the problem, but now sometimes my application crash unceremoniously at runtime. Now I'm trying to solve that :P

This post help me to clarify some doubt.
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Paresh April 25, 2014 @ 3:12am
I am using West-wind SQL resource provider in asp.net with framewrok 4.5.1.
I added it using NuGet package. When i click "Generate Local Resource" in "Tool" menu, it gives "Object reference not set to an instance of an object".
Manually created resource file works, but is not generating resource automatically.
Can anybody suggest what is wrong with it or from where i can download latest resource provider DLLs without Nuget which support 4.5.1 framework?
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by mgpmul May 31, 2014 @ 6:04am
Nice that one can require a specific verision in YourApp.exe.config. Just wondering: how is this piece of xml information evaluated? What piece of information is consulted to decide wether or not it is 4.5? Is it the registry entry "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\"?
# re: .NET 4.5 is an in-place replacement for .NET 4.0
by Adam Plocher October 26, 2014 @ 3:57pm
Windows 10 Tech Preview build 9860 returns 4.0.30319.0 from Environment.Version. This means any version detection used in code is going to fail if you need the revision #. For example, I can't run Sharp Develop 5.0 RC because of this. See screenshot: http://i.imgur.com/S8ai4IZ.png
 


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2014