How can I find the version of .NET run-time programmatically?

前端 未结 2 1660
情书的邮戳
情书的邮戳 2021-02-05 06:48

I need a solution to give me the .NET run-time version of both the full framework as well as the .NET Core.

On a machine with the following .NET

相关标签:
2条回答
  • 2021-02-05 07:28

    If you want to know which version of .NET Framework is installed on a machine you should use the documented 'Release Key' Registry Key. That key is registered in the system when .NET Framework is installed.

    This is publicly documented here: https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/versions-and-dependencies

    You have to write the code that will read that registry key and map it to an actual .NET Framework version. Here is code that does that for .NET Framework versions betwee 4.5 and 4.7.1. You can further customize that as you need to. (from https://github.com/dotnet/corefx/blob/master/src/CoreFx.Private.TestUtilities/src/System/PlatformDetection.NetFx.cs#L33)

        private static Version GetFrameworkVersion()
        {
            using (RegistryKey ndpKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"))
            {
                if (ndpKey != null)
                {
                    int value = (int)(ndpKey.GetValue("Release") ?? 0);
                    if (value >= 528040) 
                        return new Version(4, 8, 0);
    
                    if (value >= 461808) 
                        return new Version(4, 7, 2);
    
                    if (value >= 461308)
                        return new Version(4, 7, 1);
    
                    if (value >= 460798)
                        return new Version(4, 7, 0);
    
                    if (value >= 394802)
                        return new Version(4, 6, 2);
    
                    if (value >= 394254)
                        return new Version(4, 6, 1);
    
                    if (value >= 393295)
                        return new Version(4, 6, 0);
    
                    if (value >= 379893)
                        return new Version(4, 5, 2);
    
                    if (value >= 378675)
                        return new Version(4, 5, 1);
    
                    if (value >= 378389)
                        return new Version(4, 5, 0);
    
                    throw new NotSupportedException($"No 4.5 or later framework version detected, framework key value: {value}");
                }
    
                throw new NotSupportedException(@"No registry key found under 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' to determine running framework version");
            }
        }
    

    I know you said that you don't want to use the registry, however I recommend you use the registry path if you are running on .NET Framework (you can detect that by looking at the path where assembly containing System.Object is loaded from) as that is the recommended and supported way (we use the same inside the .NET Runtime when we need to check what version is installed on a machine).

    For .NET Core there isn't a registry key you can check. However, you can use the location of the assembly that contains System.Object to identify the version on which your code is running on.

        public static Version GetVersion()
        {
            string runtimePath = System.IO.Path.GetDirectoryName(typeof(object).Assembly.Location);
            // Making the assumption that the path looks like this
            // C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.0.6
            string version = runtimePath.Substring(runtimePath.LastIndexOf('\\') + 1);
    
            return new Version(version);
        }
    
    0 讨论(0)
  • 2021-02-05 07:42

    There isn't a unified way to do this yet, although there is an open request for this here that you can track. If you click through the various issues that reference that discussion and the issues referenced further downstream, you'll see there are also some bugs in some implementations right now, but there is active work (one of the issues had a related check-in just 8 hours ago).

    For .NET Framework:

    using System;
    ...
    string ver = AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName;
    

    and for .NET Core:

    using System.Reflection;
    using System.Runtime.Versioning;
    ...
    string ver = Assembly.GetEntryAssembly()?.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName;
    

    Output:

    .NETFramework,Version=v4.5.1
    .NETCoreApp,Version=v2.0
    

    Obviously these are a bit of a hassle to use programmatically, hence the requests for a better API (including this open issue from Microsoft discussing a new API specifically focused on testing for a minimum target framework).

    The other piece of the puzzle that will probably always be impossible is that a given application can reference many targets. Under the hood you might be pulling in .NET Standard 2.x and .NET Standard 1.x libraries, for example. I doubt there will ever be a good way to get a complete picture of all the targets behind a given collection of executing assemblies...

    0 讨论(0)
提交回复
热议问题