Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / multimedia / GDI+

.NET Versioning and Multi-targeting on C# Application and Component

4.92/5 (19 votes)
3 May 2016CPOL8 min read 60.5K  
this post discussed .NET versioning and multi-targeting of .NET application and component written in C#.

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.

Image 1

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.

XML
<!--?xml version="1.0" encoding="utf-8" ?-->
<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:

XML
<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.

Image 2

SKU attribute vs. application target framework versions

Please pay attention to the row 1 below the header:

XML
<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]:

  1. 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.)

  2. 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.

  3. 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].

Image 3

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:

XML
<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.

  1. 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:

    XML
    <configuration>
       <startup>
          <supportedruntime version="v4.0"> 
          <supportedruntime version="v2.0.50727"> 
       </supportedruntime></supportedruntime></startup>
    </configuration>  
  2. 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:

    XML
    <configuration>
       <startup>
          <supportedruntime sku=".NETFramework,
          Version=v4.0,Profile=Client" version="v4.0">
       </supportedruntime></startup>
    </configuration>  
  3. 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:

    XML
    <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

  1. .NET Versioning and Multi-Targeting - .NET 4.5 is an in-place upgrade to .NET 4.0
    http://www.hanselman.com/blog/NETVersioningAndMultiTargetingNET45IsAnInplaceUpgradeToNET40.aspx
  2. 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
  3. .NET Framework Versions and Dependencies
    https://msdn.microsoft.com/en-us/library/bb822049(v=vs.110).aspx
  4. Application Compatibility in the .NET Framework
    https://msdn.microsoft.com/en-us/library/dn458358(v=vs.110).aspx
  5. Version Compatibility in the .NET Framework
    https://msdn.microsoft.com/en-us/library/ff602939(v=vs.110).aspx
  6. 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
  7. ComponentGuaranteesAttribute Class
    https://msdn.microsoft.com/en-us/library/system.runtime.versioning.componentguaranteesattribute(v=vs.110).aspx
  8. supportedRuntime Element
    https://msdn.microsoft.com/en-us/library/w4atty68(v=vs.110).aspx
  9. Introduction to .NET Framework Compatibility

History

  • 03-13-2015: Initialized this article
  • 06-27-2015: Added more contents

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)