Introduction
This post is to share my research on the .NET Framework versioning and multi-targeting. Based on my research, I come up with some guidelines on how to build our C# application or component to target different versions of .NET frameworks to deploy on end users computers. So these guidelines will help us to get happy and smooth customer experiences. Windows Application and user control for Windows Form written in C# is in my mind.
WARNING: My post is lengthy and tedious, but if you read through with patience, you will benefit from it.
This post will answer one question: what version of .NET CLR runtime shall we target our application?
Background
Since 2002, Microsoft has delivered .NET Framework from 1.0, 1.1, 2.0, 3.0, 3.5, 4.0, and 4.5. Up to today, I have installed .NET Framework 4.5.2 on my computer. In the next release .NET framework 4.6, it will replace 4.0, 4.5, 4.5.1, 4.5.2. At the same time, Visual Studio IDE went through version Visual .Studio .NET, 2003, 2005,2008,2010, 2012, 2013. Next release will be Visual Studio 2015. From Visual Studio 2010, we can compile application targeting different .NET Framework.
For Windows version, XP is obsolete, we have Vista, 7, 8, 8.1 at this time.
The consequent question is: based on so many different versions of .NET Framework and OS version, how do we target our application or user control to run smoothly on customers' computers?
From reference [1] and [2], we can see users meet challenges and confusions when .NET framework 4.5 in-place replace 4.0. These two references are very good to clear these confusions.
.NET Framework Status
Please see the following table to see the .NET Framework and underline .NET CLR runtime versions.
We can see that .NET 3.0 and 3.5 is in-place upgrade of .NET 2.0 because CLR is the same 2.0.
For .NET 4.5, it is an in-place upgrade of .NET 4.0, but actually underline .NET CLR is updated too, but still labeled version 4.0.30319, but the build # is 17379, not 269. Please see reference [2] for detailed investigation.
.NET Framework version CLR runtime version .NET 1.1 .NET 1.0 CLR .NET 2.0, 3.0, 3.5 NET 2.0 CLR .NET 4.0,4.5(4.5.1 & 4.5.2), .NET 4.0 CLR.
.NET Framework Versions and Dependencies
Currently in the market, we have Windows version from Vista, 7 8.0 and 8.1. what is the situation of .NET framework version installed with them? This fact will help us to decide what CLR runtime our application shall target.
From reference[3], we can see the relations between OS version and CLR runtime versions. The following image is copied from that article.
From this article, we can see Windows Vista was released with .NET framework 3.0, shortly on updated to .NET 3.5. Users can keep updating it to .NET framework 4.5.2.
Windows 7 and 8.0, and 8.1 were released with .NET framework 3.5. Users can keep updating to .NET framework 4.5.2.
An Example to Use supportedRuntime Element
In reference[1], there is an example to show how to use supportedRuntime
element. Let's say, if we build our application to target .NET framework 4.5, but we don't know if user machine has installed such version, then we can use configuration file to prompt user to install it if .NET Framework 4.5 is not installed. So users get a clear clue to know what to do, instead just see your application mysteriously crash. Put this app configuration file in the same directory as executable file and named it as app.config.
<configuration>
<startup>
<supportedruntime sku=".NETFramework,Version=v4.5" version="v4.0">
</supportedruntime></startup>
</configuration>
This supportedRuntime
element is detailed in reference[8]. From this article [8], we can see supportedRuntime
element can be used multiple times:
<configuration>
<startup>
<supportedruntime version="v1.1.4322">
<supportedruntime version="v1.0.3705">
</supportedruntime></supportedruntime></startup>
</configuration>
SKU Attribute in supportedRuntime Element vs. Application Build Target Profile
In [8], we can see the relationship between SKU attribute and application target framework. The application target framework is set in Visual Studio 2013(any version is the same) project properties page=>Application tab.
SKU attribute vs. application target framework versions
Please pay attention to the row 1 below the header:
<configuration>
<startup>
<supportedruntime sku=".NETFramework,Version=v4.0,Profile=Client">
</supportedruntime></startup>
</configuration>
If we build our application to target framework 4.0, ro 4.5, either full or client profile, we can set up supportedRuntime
as above. It will work for all these target frameworks.
How the Order of .NET Framework Version is Decided When An Application Runs
When an application written in C# starts to run, it needs to start, or activate the CLR in order to run managed code. Typically, a .NET Framework app runs on the version of the CLR that it was built on, but you can change this behaviour by using application configuration file.
The version of .NET Framework that an app runs on is determined in the following order[6]:
- Configuration file
If the application configuration file includes <supportedruntime> entries that specify one or more .NET Framework versions, and one of those versions is present on the user's computer, the app runs on that version. The configuration file reads <supportedruntime> entries in the order they are listed, and uses the first .NET Framework version listed that is present on the user's computer. (Use the <requiredruntime> element for version 1.0.)
- Compiled version
If there is no configuration file, but the version of the .NET Framework that the app was built on is present on the user's computer, the app runs on that version.
- Latest version installed
If the version of the .NET Framework that the app was built on is not present and a configuration file does not specify a version in a <supportedruntime> element, the app tries to run on the latest version of the .NET Framework that is present on the user's computer.
If our app supports both the .NET Framework 3.5 and 4 or later, we can use multiple supportedRuntime
element entries in the configuration file to avoid .NET Framework initialization errors. For more information, see [3].
We can also configure your .NET Framework 3.5 apps to run on the .NET Framework 4 or 4.5, even on computers that have the .NET Framework 3.5 installed, to take advantage of the performance improvements in versions 4 and 4.5.
To emphasize one more time, please pay attention to 1) Configure file that how multiple supportedRuntime
entries are used. So we can utilized the multiple supportedRuntime
elements in different order to meet our needs. Please see the following table I screenshot from [6].
App Config settings table
Please pay special attention to row 4 below table header. multiple entries of supportedRuntime
element are used. This setting works for the machine with any of .NET framework 3.5 or .NET framework 4.0, or .NET framework 4.5 installed. So we can set up supportedRuntime
elements as this:
<configuration>
<startup>
<supportedruntime version="v4.0">
<supportedruntime version="v2.0.50727">
</supportedruntime></supportedruntime></startup>
</configuration>
Guidelines to Build Application in C#
Based on the above discovery, we can have these guidelines to build our application. Our build can be 32bit only because the 32 bit application can always run 64 bit machine.
-
To target all Windows versions: Vista, 7,8.0, 8.1.
We can build our application targeting .NET framework 3.5, but add the following supportedRuntime
element in the app configure file:
<configuration>
<startup>
<supportedruntime version="v4.0">
<supportedruntime version="v2.0.50727">
</supportedruntime></supportedruntime></startup>
</configuration>
-
To target application on .NET framework 4.0.
We can build our application targeting .NET framework 4.0 and add the following supportedRuntime
element in the app configure file:
<configuration>
<startup>
<supportedruntime sku=".NETFramework,
Version=v4.0,Profile=Client" version="v4.0">
</supportedruntime></startup>
</configuration>
-
To be little aggressive, To target .NET framework 4.5 directly
We can build our application targeting .NET framework .4.5 directly and add the following supportedRuntime
in the app configure file:
<configuration>
<startup>
<supportedruntime sku=".NETFramework,Version=v4.5" version="v4.0">
</supportedruntime></startup>
</configuration>
In this case, if the user machine does not have .NET framework 4.5 installed, it will prompt user to install it in a nice way instead of crashing silently.
Recent Updates
Based the blog[9], the .NET Framework 4.0, 4.5, and 4.5.1 now are out of support. Please note that targeting these Frameworks while running on a newer .NET Framework version will continue to be supported as per the newer Framework’s support policy.
So developers will face compatibility issue. Beginning with the .NET Framework 4.5.1, compatibility issues are categorized as either ‘runtime changes’ or ‘retargeting changes’. More details can refer to [9].
Conclusion
After lengthy discussion and evidences, we get the above guidelines to build the right version of application and user control in C#.
If I miss anything or make a mistake any point, please let me know. Your feedbacks are welcome. I am happy to see more members benefit from this post.
References
- .NET Versioning and Multi-Targeting - .NET 4.5 is an in-place upgrade to .NET 4.0
http://www.hanselman.com/blog/NETVersioningAndMultiTargetingNET45IsAnInplaceUpgradeToNET40.aspx - https://weblog.west-wind.com/posts/2012/Mar/13/NET-45-is-an-inplace-replacement-for-NET-40
https://weblog.west-wind.com/posts/2012/Mar/13/NET-45-is-an-inplace-replacement-for-NET-40 - .NET Framework Versions and Dependencies
https://msdn.microsoft.com/en-us/library/bb822049(v=vs.110).aspx - Application Compatibility in the .NET Framework
https://msdn.microsoft.com/en-us/library/dn458358(v=vs.110).aspx - Version Compatibility in the .NET Framework
https://msdn.microsoft.com/en-us/library/ff602939(v=vs.110).aspx - How to: Configure an App to Support .NET Framework 4 or 4.5
https://msdn.microsoft.com/en-us/library/jj152935(v=vs.110).aspx - ComponentGuaranteesAttribute Class
https://msdn.microsoft.com/en-us/library/system.runtime.versioning.componentguaranteesattribute(v=vs.110).aspx - supportedRuntime Element
https://msdn.microsoft.com/en-us/library/w4atty68(v=vs.110).aspx - Introduction to .NET Framework Compatibility
History
- 03-13-2015: Initialized this article
- 06-27-2015: Added more contents