Czy istnieje łatwy sposób sprawdzenia wersji .NET Framework?


86

Problem polega na tym, że muszę wiedzieć, czy to wersja 3.5 SP 1. Environment.Version()tylko zwraca 2.0.50727.3053.

Znalazłem to rozwiązanie , ale myślę, że zajmie to znacznie więcej czasu niż jest to warte, więc szukam prostszego. Czy to możliwe?


2
Bez dalszych badań Environment.Version()prawdopodobnie po prostu zwraca wersję CLR.
Cecil ma imię

Environment.Version () daje, 2.0nawet jeśli działa z 3.5
LCJ

Użyłem podejścia wspomnianego na stackoverflow.com/questions/15128426/ ...
LCJ


2
@Lijo, dla .NET 3.5, wersja CLR to w rzeczywistości 2.0.
Mathias Lykkegaard Lorenzen

Odpowiedzi:


106

Coś takiego powinno to zrobić. Po prostu pobierz wartość z rejestru

W przypadku platformy .NET 1-4 :

Frameworkto najwyższa zainstalowana wersja, SPto dodatek Service Pack dla tej wersji.

RegistryKey installed_versions = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP");
string[] version_names = installed_versions.GetSubKeyNames();
//version names start with 'v', eg, 'v3.5' which needs to be trimmed off before conversion
double Framework = Convert.ToDouble(version_names[version_names.Length - 1].Remove(0, 1), CultureInfo.InvariantCulture);
int SP = Convert.ToInt32(installed_versions.OpenSubKey(version_names[version_names.Length - 1]).GetValue("SP", 0));

W przypadku platformy .NET 4.5+ (z oficjalnej dokumentacji ):

using System;
using Microsoft.Win32;


...


private static void Get45or451FromRegistry()
{
    using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\")) {
        int releaseKey = Convert.ToInt32(ndpKey.GetValue("Release"));
        if (true) {
            Console.WriteLine("Version: " + CheckFor45DotVersion(releaseKey));
        }
    }
}


...


// Checking the version using >= will enable forward compatibility,  
// however you should always compile your code on newer versions of 
// the framework to ensure your app works the same. 
private static string CheckFor45DotVersion(int releaseKey)
{
    if (releaseKey >= 461808) {
        return "4.7.2 or later";
    }
    if (releaseKey >= 461308) {
        return "4.7.1 or later";
    }
    if (releaseKey >= 460798) {
        return "4.7 or later";
    }
    if (releaseKey >= 394802) {
        return "4.6.2 or later";
    }
    if (releaseKey >= 394254) {
        return "4.6.1 or later";
    }
    if (releaseKey >= 393295) {
        return "4.6 or later";
    }
    if (releaseKey >= 393273) {
        return "4.6 RC or later";
    }
    if ((releaseKey >= 379893)) {
        return "4.5.2 or later";
    }
    if ((releaseKey >= 378675)) {
        return "4.5.1 or later";
    }
    if ((releaseKey >= 378389)) {
        return "4.5 or later";
    }
    // This line should never execute. A non-null release key should mean 
    // that 4.5 or later is installed. 
    return "No 4.5 or later version detected";
}

Długi ciąg wersji, a także podklucz SP dla każdego SOFTWARE \ Microsoft \ NET Framework Setup \ NDP \ <. Net version> powinny to zapewniać, co można pobrać za pomocą metody GetValue.
Factor Mystic

21
Czy nie dałoby to po prostu najwyższej ZAINSTALOWANEJ wersji .NET na komputerze - a nie wersji, na której działa aplikacja?
Grinn

2
@FactorMystic: Cześć, użyłem twojego kodu, aby sprawdzić najnowszą wersję, ale nie wyświetla wersji 4.5, nawet jeśli jest zainstalowana na moim komputerze. Proszę, prowadź mnie
Upendra Chaudhari,

1
@FactorMystic Czy można to zrobić na koncie PC bez administratora? czy będę mieć dostęp do wartości rejestru?
Jay Nirgudkar

2
@FactorMystic jaki jest sens if (true)sprawdzania? Dlaczego nie tylko wezwanie Console.WriteLine()?
Broots Waymb

22

Nie wiem, dlaczego nikt nie zaproponował po oficjalnych zaleceń Microsoftu prawo tutaj .

To jest kod, który polecają. Jasne, że jest brzydki, ale działa.

W przypadku platformy .NET 1-4

private static void GetVersionFromRegistry()
{
     // Opens the registry key for the .NET Framework entry. 
        using (RegistryKey ndpKey = 
            RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "").
            OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
        {
            // As an alternative, if you know the computers you will query are running .NET Framework 4.5  
            // or later, you can use: 
            // using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,  
            // RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
        foreach (string versionKeyName in ndpKey.GetSubKeyNames())
        {
            if (versionKeyName.StartsWith("v"))
            {

                RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
                string name = (string)versionKey.GetValue("Version", "");
                string sp = versionKey.GetValue("SP", "").ToString();
                string install = versionKey.GetValue("Install", "").ToString();
                if (install == "") //no install info, must be later.
                    Console.WriteLine(versionKeyName + "  " + name);
                else
                {
                    if (sp != "" && install == "1")
                    {
                        Console.WriteLine(versionKeyName + "  " + name + "  SP" + sp);
                    }

                }
                if (name != "")
                {
                    continue;
                }
                foreach (string subKeyName in versionKey.GetSubKeyNames())
                {
                    RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
                    name = (string)subKey.GetValue("Version", "");
                    if (name != "")
                        sp = subKey.GetValue("SP", "").ToString();
                    install = subKey.GetValue("Install", "").ToString();
                    if (install == "") //no install info, must be later.
                        Console.WriteLine(versionKeyName + "  " + name);
                    else
                    {
                        if (sp != "" && install == "1")
                        {
                            Console.WriteLine("  " + subKeyName + "  " + name + "  SP" + sp);
                        }
                        else if (install == "1")
                        {
                            Console.WriteLine("  " + subKeyName + "  " + name);
                        }

                    }

                }

            }
        }
    }

}

Dla .NET 4.5 i nowszych

// Checking the version using >= will enable forward compatibility, 
// however you should always compile your code on newer versions of
// the framework to ensure your app works the same.
private static string CheckFor45DotVersion(int releaseKey)
{
   if (releaseKey >= 393295) {
      return "4.6 or later";
   }
   if ((releaseKey >= 379893)) {
        return "4.5.2 or later";
    }
    if ((releaseKey >= 378675)) {
        return "4.5.1 or later";
    }
    if ((releaseKey >= 378389)) {
        return "4.5 or later";
    }
    // This line should never execute. A non-null release key should mean
    // that 4.5 or later is installed.
    return "No 4.5 or later version detected";
}

private static void Get45or451FromRegistry()
{
    using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\")) {
        if (ndpKey != null && ndpKey.GetValue("Release") != null) {
            Console.WriteLine("Version: " + CheckFor45DotVersion((int) ndpKey.GetValue("Release")));
        }
      else {
         Console.WriteLine("Version 4.5 or later is not detected.");
      } 
    }
}

metoda dla .NET 1-4 ma błąd: nie będzie drukować oryginalnych wersji (bez SP) do wersji 3.0
Lu55

1
A updatesdla NET Framework 4.7 i NET Framework 4.7.1 ? Nie w wersji 4.7 lub nowszej. Tak, 4.7 lub 4.7.1.
Kiquenet,

@Kiquenet czy te nie działają dla podanego kodu?
Mathias Lykkegaard Lorenzen

15

Alternatywną metodą, w której nie jest potrzebne prawo dostępu do rejestru, jest sprawdzenie, czy istnieją klasy, które zostały wprowadzone w określonych aktualizacjach frameworka.

private static bool Is46Installed()
{
    // API changes in 4.6: https://github.com/Microsoft/dotnet/blob/master/releases/net46/dotnet46-api-changes.md
    return Type.GetType("System.AppContext, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", false) != null;
}

private static bool Is461Installed()
{
    // API changes in 4.6.1: https://github.com/Microsoft/dotnet/blob/master/releases/net461/dotnet461-api-changes.md
    return Type.GetType("System.Data.SqlClient.SqlColumnEncryptionCngProvider, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", false) != null;
}

private static bool Is462Installed()
{
    // API changes in 4.6.2: https://github.com/Microsoft/dotnet/blob/master/releases/net462/dotnet462-api-changes.md
    return Type.GetType("System.Security.Cryptography.AesCng, System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", false) != null;
}

private static bool Is47Installed()
{
    // API changes in 4.7: https://github.com/Microsoft/dotnet/blob/master/releases/net47/dotnet47-api-changes.md
    return Type.GetType("System.Web.Caching.CacheInsertOptions, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false) != null;
}

Wszelkie odniesienia do 4.5?
Vinicius Gonçalves,

Podoba mi się ten pomysł
wexman

1
i 4.7.1, 4.7.2 i 4.8?
Kiquenet

Bardzo przydatne dla tych z nas, którzy mają obawy o pozwolenie
FBryant87

10

Environment.Version()podaje poprawną odpowiedź na inne pytanie. Ta sama wersja środowiska CLR jest używana w .NET 2.0, 3 i 3.5. Przypuszczam, że możesz sprawdzić GAC pod kątem bibliotek, które zostały dodane w każdym z tych kolejnych wydań.


2
Environment.Version () daje, 2.0nawet jeśli działa z 3.5
LCJ

5
Environment.Version () podaje nazwę środowiska CLR. 3.5 nie jest nową wersją CLR. To 2.0 plus kilka dodatkowych bibliotek z przyrostem 1,5 z marketingu.
Quillbreaker,

7
Odpowiedź jest myląca. CLR 2.0 jest używany dla .NET 2.0, 3.0 i 3.5. CLR został zmieniony z wersji 4. CLR 4.0 służy do .NET 4.0.
Bouvierr

9

Kiedyś było to łatwe, ale Microsoft zdecydował się na przełomową zmianę: przed wersją 4.5 każda wersja .NET znajdowała się w swoim własnym katalogu poniżej C:\Windows\Microsoft.NET\Framework(podkatalogi v1.0.3705, v1.1.4322, v2.0.50727, v3.0, v3.5i v4.0.30319).

Od wersji 4.5 zostało to zmienione: każda wersja .NET (tj. 4.5.x, 4.6.x, 4.7.x, 4.8.x, ...) jest instalowana w tym samym podkatalogu v4.0.30319- więc nie możesz już sprawdź zainstalowaną wersję .NET, zaglądając do Microsoft.NET\Framework.

Aby sprawdzić wersję .NET, firma Microsoft udostępniła dwa różne przykładowe skrypty w zależności od wersji .NET, która jest sprawdzana, ale nie podoba mi się posiadanie dwóch różnych skryptów C # do tego. Spróbowałem więc połączyć je w jeden, oto skrypt, GetDotNetVersion.csktóry stworzyłem (i zaktualizowałem do frameworka 4.7.1):

using System;
using Microsoft.Win32;
public class GetDotNetVersion
{
    public static void Main(string[] args)
    {
        Console.WriteLine((args != null && args.Length > 0) 
                          ? "Command line arguments: " + string.Join(",", args) 
                          : "");

        string maxDotNetVersion = GetVersionFromRegistry();
        if (String.Compare(maxDotNetVersion, "4.5") >= 0)
        {
            string v45Plus = GetDotNetVersion.Get45PlusFromRegistry();
            if (v45Plus != "") maxDotNetVersion = v45Plus;
        }
        Console.WriteLine("*** Maximum .NET version number found is: " + maxDotNetVersion + "***");
    }

    private static string Get45PlusFromRegistry()
    {
        String dotNetVersion = "";
        const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\";
        using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey))
        {
            if (ndpKey != null && ndpKey.GetValue("Release") != null)
            {
                dotNetVersion = CheckFor45PlusVersion((int)ndpKey.GetValue("Release"));
                Console.WriteLine(".NET Framework Version: " + dotNetVersion);
            }
            else
            {
                Console.WriteLine(".NET Framework Version 4.5 or later is not detected.");
            }
        }
        return dotNetVersion;
    }

    // Checking the version using >= will enable forward compatibility.
    private static string CheckFor45PlusVersion(int releaseKey)
    {
        if (releaseKey >= 528040) return "4.8 or later";
        if (releaseKey >= 461808) return "4.7.2";
        if (releaseKey >= 461308) return "4.7.1";
        if (releaseKey >= 460798) return "4.7";
        if (releaseKey >= 394802) return "4.6.2";
        if (releaseKey >= 394254) return "4.6.1";
        if (releaseKey >= 393295) return "4.6";
        if ((releaseKey >= 379893)) return "4.5.2";
        if ((releaseKey >= 378675)) return "4.5.1";
        if ((releaseKey >= 378389)) return "4.5";

        // This code should never execute. A non-null release key should mean
        // that 4.5 or later is installed.
        return "No 4.5 or later version detected";
    }

    private static string GetVersionFromRegistry()
    {
        String maxDotNetVersion = "";
        // Opens the registry key for the .NET Framework entry.
        using (RegistryKey ndpKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "")
                                        .OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
        {
            // As an alternative, if you know the computers you will query are running .NET Framework 4.5 
            // or later, you can use:
            // using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, 
            // RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
            foreach (string versionKeyName in ndpKey.GetSubKeyNames())
            {
                if (versionKeyName.StartsWith("v"))
                {
                    RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
                    string name = (string)versionKey.GetValue("Version", "");
                    string sp = versionKey.GetValue("SP", "").ToString();
                    string install = versionKey.GetValue("Install", "").ToString();
                    if (install == "") //no install info, must be later.
                    {
                        Console.WriteLine(versionKeyName + "  " + name);
                        if (String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                    }
                    else
                    {
                        if (sp != "" && install == "1")
                        {
                            Console.WriteLine(versionKeyName + "  " + name + "  SP" + sp);
                            if (String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                        }

                    }
                    if (name != "")
                    {
                        continue;
                    }
                    foreach (string subKeyName in versionKey.GetSubKeyNames())
                    {
                        RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
                        name = (string)subKey.GetValue("Version", "");
                        if (name != "")
                        {
                            sp = subKey.GetValue("SP", "").ToString();
                        }
                        install = subKey.GetValue("Install", "").ToString();
                        if (install == "")
                        {
                            //no install info, must be later.
                            Console.WriteLine(versionKeyName + "  " + name);
                            if (String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                        }
                        else
                        {
                            if (sp != "" && install == "1")
                            {
                                Console.WriteLine("  " + subKeyName + "  " + name + "  SP" + sp);
                                if (String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                            }
                            else if (install == "1")
                            {
                                Console.WriteLine("  " + subKeyName + "  " + name);
                                if (String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                            } // if
                        } // if
                    } // for
                } // if
            } // foreach
        } // using
        return maxDotNetVersion;
    }
    
} // class

Na moim komputerze wyświetla:

2.0.50727 2.0.50727.4927 SP2
v3.0 3.0.30729.4926 SP2
v3.5 3.5.30729.4926 SP1
v4
Klient 4.7.03056
Pełna 4.7.03056
v4.0
Klient 4.0.0.0
.NET Framework Wersja: 4.7.2 lub nowsza
*** * Maksymalny znaleziony numer wersji .NET to: 4.7.2 lub nowszy ****

Jedyną rzeczą, którą należy utrzymać w czasie, jest numer kompilacji, gdy pojawi się wersja .NET wyższa niż 4.7.1 - można to łatwo zrobić, modyfikując funkcję CheckFor45PlusVersion, musisz znać klucz wydania nowej wersji, a następnie można to dodać. Na przykład:

if (releaseKey >= 461308) return "4.7.1 or later";

Ten klucz wydania jest nadal najnowszy i ważny dla aktualizacji Fall Creators dla systemu Windows 10. Jeśli nadal korzystasz z innych (starszych) wersji systemu Windows, istnieje inna zgodna z dokumentacją firmy Microsoft:

NET Framework 4.7.1 zainstalowany we wszystkich innych wersjach systemu operacyjnego Windows 461310

Więc jeśli tego również potrzebujesz, musisz dodać

if (releaseKey >= 461310) return "4.7.1 or later";

na górę funkcji CheckFor45PlusVersion. Podobnie działa w nowszych wersjach. Na przykład ostatnio dodałem czek na 4.8. Te numery kompilacji można znaleźć zwykle w firmie Microsoft.


Uwaga: nie potrzebujesz do zainstalowania Visual Studio, nawet PowerShell - możesz użyć csc.exedo skompilowania i uruchomienia powyższego skryptu, który opisałem tutaj.


Aktualizacja: Pytanie dotyczy .NET Framework, ze względu na kompletność chciałbym również wspomnieć, jak zapytać o wersję .NET Core - w porównaniu z powyższym, to jest łatwe: Otwórz powłokę poleceń i wpisz:

dotnet --info Enter

i wyświetli numer wersji .NET Core, wersję systemu Windows i wersje każdej powiązanej biblioteki DLL środowiska wykonawczego. Przykładowe dane wyjściowe:

NET Core SDK (odzwierciedlający dowolny global.json):
  wersja: 2.1.300
  Commit: adab45bf0c

Środowisko wykonawcze:
  nazwa systemu
  operacyjnego : Windows Wersja systemu operacyjnego: 10.0.15063
  Platforma systemu operacyjnego: Windows
  RID: win10-x64
  ścieżka podstawowa: C: \ Program Files \ dotnet \ sdk \ 2.1.300


Host (przydatne do obsługi):
  Wersja: 2.1.0
  Commit: caa7b7e2ba

.NET Core SDK zainstalowane:
  1.1.9 [C: \ Program Files \ dotnet \ sdk]
  2.1.102 [C: \ Program Files \ dotnet \ sdk]
  ...
  2.1.300 [C: \ Program Files \ dotnet \ sdk]

.NET Core zainstalowane środowiska wykonawcze:
  Microsoft.AspNetCore.All 2.1.0 [C: \ Program
  Files \ dotnet \ shared \ Microsoft .AspNetCore.All]
  ...
  Microsoft.NETCore.App 2.1.0 [C: \ Program Files \ dotnet \ shared \ Microsoft.NETCore.App]

Aby zainstalować dodatkowe środowiska wykonawcze lub SDK platformy .NET Core:
  https://aka.ms/dotnet-download

Zwróć na to uwagę

  • jeśli potrzebujesz tylko numeru wersji bez wszystkich dodatkowych informacji, możesz użyć
    dotnet --version.

  • na 64-bitowym systemie Windows PC , możliwe jest zainstalowanie x86 wersji obok siebie z x64 wersji .NET Core. W takim przypadku otrzymasz tylko wersję, która jest pierwsza w zmiennej środowiskowej PATH. Jest to szczególnie ważne, jeśli chcesz go aktualizować i chcesz znać każdą wersję. Aby zapytać o obie wersje, użyj:

C: \ Program Files \ dotnet \ dotnet.exe --version
3.0.100-preview6-012264
C: \ Program Files (x86) \ dotnet \ dotnet.exe --version
3.0.100-preview6-012264

W powyższym przykładzie oba są takie same, ale jeśli zapomniałeś zaktualizować obu instancji, możesz uzyskać różne wyniki! Zauważ, że Program Filesdotyczy to wersji 64-bitowej i Program Files (x86)jest to wersja 32-bitowa .


Aktualizacja: Jeśli wolisz zachować numery kompilacji na liście, a nie w kaskadzie instrukcji if (zgodnie z sugestią firmy Microsoft), możesz użyć tego kodu CheckFor45PlusVersionzamiast:

private static string CheckFor45PlusVersion(int releaseKey)
{
    var release = new Dictionary<int, string>()
    {
            { 378389, "4.5" },
            { 378675, "4.5.1" }, { 379893, "4.5.2" },
            { 393295, "4.6" },
            { 394254, "4.6.1" }, { 394802, "4.6.2" },
            { 460798, "4.7" },
            { 461308, "4.7.1" }, { 461808, "4.7.2" },
            { 528040, "4.8 or later" }
    };
    int result = -1;
    foreach(var k in release.OrderBy(k=>k.Key))
    {
        if (k.Key <= releaseKey) result = k.Key; else break;
    };
    return (result > 0) ? release[result] : "No 4.5 or later version detected";
}

6

AFAIK nie ma wbudowanej metody w frameworku, która pozwoli ci to zrobić. Możesz sprawdzić ten post, aby uzyskać sugestię dotyczącą określenia wersji frameworka, czytając wartości rejestru systemu Windows.


5

Ta klasa umożliwia aplikacji wysyłanie wdzięcznych powiadomień zamiast awarii i nagrania, jeśli nie może znaleźć odpowiedniej wersji .NET. Wszystko, co musisz zrobić, to w swoim głównym kodzie:

[STAThread]
static void Main(string[] args)
{
    if (!DotNetUtils.IsCompatible())
        return;
   . . .
}

Domyślnie zajmuje 4.5.2, ale możesz dostosować ją do swoich upodobań, klasę (możesz zamienić MessageBox na konsolę):

Zaktualizowano do wersji 4.8:

public class DotNetUtils
{
    public enum DotNetRelease
    {
        NOTFOUND,
        NET45,
        NET451,
        NET452,
        NET46,
        NET461,
        NET462,
        NET47,
        NET471,
        NET472,
        NET48,
    }

    public static bool IsCompatible(DotNetRelease req = DotNetRelease.NET452)
    {
        DotNetRelease r = GetRelease();
        if (r < req)
        {
            MessageBox.Show(String.Format("This this application requires {0} or greater.", req.ToString()));
            return false;
        }
        return true;
    }

    public static DotNetRelease GetRelease(int release = default(int))
    {
        int r = release != default(int) ? release : GetVersion();
        if (r >= 528040) return DotNetRelease.NET48;
        if (r >= 461808) return DotNetRelease.NET472;
        if (r >= 461308) return DotNetRelease.NET471;
        if (r >= 460798) return DotNetRelease.NET47;
        if (r >= 394802) return DotNetRelease.NET462;
        if (r >= 394254) return DotNetRelease.NET461;
        if (r >= 393295) return DotNetRelease.NET46;
        if (r >= 379893) return DotNetRelease.NET452;
        if (r >= 378675) return DotNetRelease.NET451;
        if (r >= 378389) return DotNetRelease.NET45;
        return DotNetRelease.NOTFOUND;
    }

    public static int GetVersion()
    {
        int release = 0;
        using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)
                                            .OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\"))
        {
            release = Convert.ToInt32(key.GetValue("Release"));
        }
        return release;
    }
}

Łatwo rozszerzalne, gdy później dodadzą nową wersję. Nie zawracałem sobie głowy niczym przed 4.5, ale masz pomysł.


1
Zaktualizowano dla 4.7.1, numer wersji został pobrany z docs.microsoft.com/en-us/dotnet/framework/migration-guide/…
codenamezero

Niezły pomysł IsCompatible()- zgodność jest prawdopodobnie najczęstszym powodem wysyłania zapytań do wersji .Net.
spacer

3
public class DA
{
    public static class VersionNetFramework
    {
        public static string GetVersion()
        {
            return Environment.Version.ToString();
        }
        public static string GetVersionDicription()
        {
            int Major = Environment.Version.Major;
            int Minor = Environment.Version.Minor;
            int Build = Environment.Version.Build;
            int Revision = Environment.Version.Revision;

            //http://dzaebel.net/NetVersionen.htm
            //http://stackoverflow.com/questions/12971881/how-to-reliably-detect-the-actual-net-4-5-version-installed

            //4.0.30319.42000 = .NET 4.6 on Windows 8.1 64 - bit
            if ((Major >=4) && (Minor >=0) && (Build >= 30319) && (Revision >= 42000))
                return @".NET 4.6 on Windows 8.1 64 - bit or later";
            //4.0.30319.34209 = .NET 4.5.2 on Windows 8.1 64 - bit
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 34209))
                return @".NET 4.5.2 on Windows 8.1 64 - bit or later";
            //4.0.30319.34209 = .NET 4.5.2 on Windows 7 SP1 64 - bit
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 34209))
                return @".NET 4.5.2 on Windows 7 SP1 64 - bit or later";
            //4.0.30319.34014 = .NET 4.5.1 on Windows 8.1 64 - bit
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 34014))
                return @".NET 4.5.1 on Windows 8.1 64 - bit or later";
            //4.0.30319.18444 = .NET 4.5.1 on Windows 7 SP1 64 - bit(with MS14 - 009 security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 18444))
                return @".NET 4.5.1 on Windows 7 SP1 64 - bit(with MS14 - 009 security update) or later";
            //4.0.30319.18408 = .NET 4.5.1 on Windows 7 SP1 64 - bit
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 18408))
                return @".NET 4.5.1 on Windows 7 SP1 64 - bit or later";
            //4.0.30319.18063 = .NET 4.5 on Windows 7 SP1 64 - bit(with MS14 - 009 security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 18063))
                return @".NET 4.5 on Windows 7 SP1 64 - bit(with MS14 - 009 security update) or later";
            //4.0.30319.18052 = .NET 4.5 on Windows 7 SP1 64 - bit
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 18052))
                return @".NET 4.5 on Windows 7 SP1 64 - bit or later";
            //4.0.30319.18010 = .NET 4.5 on Windows 8
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 18010))
                return @".NET 4.5 on Windows 8 or later";
            //4.0.30319.17929 = .NET 4.5 RTM
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 17929))
                return @".NET 4.5 RTM or later";
            //4.0.30319.17626 = .NET 4.5 RC
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 17626))
                return @".NET 4.5 RC or later";
            //4.0.30319.17020.NET 4.5 Preview, September 2011
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 17020))
                return @".NET 4.5 Preview, September 2011 or later";
            //4.0.30319.2034 = .NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS14 - 009 LDR security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 2034))
                return @".NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS14 - 009 LDR security update) or later";
            //4.0.30319.1026 = .NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS14 - 057 GDR security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 1026))
                return @".NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS14 - 057 GDR security update) or later";
            //4.0.30319.1022 = .NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS14 - 009 GDR security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 1022))
                return @".NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS14 - 009 GDR security update) or later";
            //4.0.30319.1008 = .NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS13 - 052 GDR security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 1008))
                return @".NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS13 - 052 GDR security update) or later";
            //4.0.30319.544 = .NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS12 - 035 LDR security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 544))
                return @".NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS12 - 035 LDR security update) or later";
            //4.0.30319.447   yes built by: RTMLDR, .NET 4.0 Platform Update 1, April 2011
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 447))
                return @"built by: RTMLDR, .NET 4.0 Platform Update 1, April 2011 or later";
            //4.0.30319.431   yes built by: RTMLDR, .NET 4.0 GDR Update, March 2011 / with VS 2010 SP1 / or.NET 4.0 Update
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 431))
                return @"built by: RTMLDR, .NET 4.0 GDR Update, March 2011 / with VS 2010 SP1 / or.NET 4.0 Update or later";
            //4.0.30319.296 = .NET 4.0 on Windows XP SP3, 7(with MS12 - 074 GDR security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 296))
                return @".NET 4.0 on Windows XP SP3, 7(with MS12 - 074 GDR security update) or later";
            //4.0.30319.276 = .NET 4.0 on Windows XP SP3 (4.0.3 Runtime update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 276))
                return @".NET 4.0 on Windows XP SP3 (4.0.3 Runtime update) or later";
            //4.0.30319.269 = .NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS12 - 035 GDR security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 269))
                return @".NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS12 - 035 GDR security update) or later";
            //4.0.30319.1 yes built by: RTMRel, .NET 4.0 RTM Release, April 2010
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 1))
                return @"built by: RTMRel, .NET 4.0 RTM Release, April 2010 or later";

            //4.0.30128.1     built by: RC1Rel, .NET 4.0 Release Candidate, Feb 2010
            if ((Major >=4) && (Minor >=0) && (Build >= 30128) && (Revision >= 1))
                return @"built by: RC1Rel, .NET 4.0 Release Candidate, Feb 2010 or later";
            //4.0.21006.1     built by: B2Rel, .NET 4.0 Beta2, Oct 2009
            if ((Major >=4) && (Minor >=0) && (Build >= 21006) && (Revision >=1))
                return @"built by: B2Rel, .NET 4.0 Beta2, Oct 2009 or later";
            //4.0.20506.1     built by: Beta1, .NET 4.0 Beta1, May 2009
            if ((Major >=4) && (Minor >=0) && (Build >= 20506) && (Revision >=1))
                return @"built by: Beta1, .NET 4.0 Beta1, May 2009 or later";
            //4.0.11001.1     built by: CTP2 VPC, .NET 4.0 CTP, October 2008
            if ((Major >=4) && (Minor >=0) && (Build >= 11001) && (Revision >=1))
                return @"built by: CTP2 VPC, .NET 4.0 CTP, October 2008 or later";

            //3.5.30729.5420  yes built by: Win7SP1, .NET 3.5.1 Sicherheits - Update, 12 April 2011
            if ((Major >=3) && (Minor >=5) && (Build >= 30729) && (Revision >= 5420))
                return @"built by: Win7SP1, .NET 3.5.1 Sicherheits - Update, 12 April 2011 or later";
            //3.5.30729.5004  yes built by: NetFXw7 / Windows 7..Rel., Jan 2010 / +Data functions KB976127 .NET 3.5 SP1
            if ((Major >=3) && (Minor >=5) && (Build >= 30729) && (Revision >= 5004))
                return @"built by: NetFXw7 / Windows 7..Rel., Jan 2010 / +Data functions KB976127 .NET 3.5 SP1 or later";
            //3.5.30729.4466  yes built by: NetFXw7 / Windows XP..Rel. , Jan 2010 / +Data functions KB976127 .NET 3.5 SP1
            if ((Major >=3) && (Minor >=5) && (Build >= 30729) && (Revision >= 4466))
                return @"built by: NetFXw7 / Windows XP..Rel. , Jan 2010 / +Data functions KB976127 .NET 3.5 SP1 or later";
            //3.5.30729.4926  yes built by: NetFXw7 / Windows 7 Release, Oct 2009 / .NET 3.5 SP1 + Hotfixes
            if ((Major >=3) && (Minor >=5) && (Build >= 30729) && (Revision >= 4926))
                return @"built by: NetFXw7 / Windows 7 Release, Oct 2009 / .NET 3.5 SP1 + Hotfixes or later";
            //3.5.30729.4918      built by: NetFXw7 / Windows 7 Release Candidate, June 2009
            if ((Major >=3) && (Minor >=5) && (Build >= 30729) && (Revision >= 4918))
                return @"built by: NetFXw7 / Windows 7 Release Candidate, June 2009 or later";
            //3.5.30729.196   yes built by: QFE, .NET 3.5 Family Update Vista / W2008, Dec 2008
            if ((Major >= 3) && (Minor >= 5) && (Build >= 30729) && (Revision >=196))
                return @"built by: QFE, .NET 3.5 Family Update Vista / W2008, Dec 2008 or later";
            //3.5.30729.1 yes built by: SP, .NET 3.5 SP1, Aug 2008
            if ((Major >= 3) && (Minor >= 5) && (Build >= 30729) && (Revision >=1))
                return @"built by: SP, .NET 3.5 SP1, Aug 2008 or later";

            //3.5.30428.1         built by: SP1Beta1, .NET 3.5 SP1 BETA1, May 2008
            if ((Major >=3) && (Minor >=5) && (Build >= 30428) && (Revision >=1))
                return @"built by: SP1Beta1, .NET 3.5 SP1 BETA1, May 2008 or later";
            //3.5.21022.8 yes built by: RTM, Jan 2008
            if ((Major >=3) && (Minor >=5) && (Build >= 21022) && (Revision >= 8))
                return @"built by: RTM, Jan 2008 or later";
            //3.5.20706.1     built by: Beta2, Orcas Beta2, Oct 2007
            if ((Major >=3) && (Minor >=5) && (Build >= 20706) && (Revision >= 1))
                return @"built by: Beta2, Orcas Beta2, Oct 2007 or later";
            //3.5.20526.0     built by: MCritCTP, Orcas Beta1, Mar 2007
            if ((Major >=3) && (Minor >=5) && (Build >= 20526) && (Revision >=0))
                return @"built by: MCritCTP, Orcas Beta1, Mar 2007 or later";

            //3.0.6920.1500   yes built by: QFE, Family Update Vista / W2008, Dez 2008, KB958483
            if ((Major >=3) && (Minor >=0) && (Build >= 6920) && (Revision >= 1500))
                return @"built by: QFE, Family Update Vista / W2008, Dez 2008, KB958483 or later";
            //3.0.4506.4926   yes(NetFXw7.030729 - 4900) / Windows 7 Release, Oct 2009
            if ((Major >=3) && (Minor >=0) && (Build >= 4506) && (Revision >= 4926))
                return @"(NetFXw7.030729 - 4900) / Windows 7 Release, Oct 2009 or later";
            //3.0.4506.4918(NetFXw7.030729 - 4900) / Windows 7 Release Candidate, June 2009
            if ((Major >=3) && (Minor >=5) && (Build >= 4506) && (Revision >= 4918))
                return @"(NetFXw7.030729 - 4900) / Windows 7 Release Candidate, June 2009 or later";
            //3.0.4506.2152       3.0.4506.2152(SP.030729 - 0100) / .NET 4.0 Beta1 / May 2009
            if ((Major >= 3) && (Minor >= 5) && (Build >= 4506) && (Revision >= 2152))
                return @"3.0.4506.2152(SP.030729 - 0100) / .NET 4.0 Beta1 / May 2009 or later";
            //3.0.4506.2123   yes(NetFX.030618 - 0000).NET 3.0 SP2, Aug 2008
            if ((Major >= 3) && (Minor >= 5) && (Build >= 4506) && (Revision >= 2123))
                return @"s(NetFX.030618 - 0000).NET 3.0 SP2, Aug 2008 or later";
            //3.0.4506.2062(SP1Beta1.030428 - 0100), .NET 3.0 SP1 BETA1, May 2008
            if ((Major >= 3) && (Minor >= 5) && (Build >= 4506) && (Revision >= 2062))
                return @"(SP1Beta1.030428 - 0100), .NET 3.0 SP1 BETA1, May 2008 or later";
            //3.0.4506.590(winfxredb2.004506 - 0590), Orcas Beta2, Oct 2007
            if ((Major >= 3) && (Minor >= 5) && (Build >= 4506) && (Revision >= 590))
                return @"(winfxredb2.004506 - 0590), Orcas Beta2, Oct 2007 or later";
            //3.0.4506.577(winfxred.004506 - 0577), Orcas Beta1, Mar 2007
            if ((Major >= 3) && (Minor >= 5) && (Build >= 4506) && (Revision >= 577))
                return @"(winfxred.004506 - 0577), Orcas Beta1, Mar 2007 or later";
            //3.0.4506.30 yes Release (.NET Framework 3.0) Nov 2006
            if ((Major >= 3) && (Minor >= 5) && (Build >= 4506) && (Revision >= 30))
                return @"Release (.NET Framework 3.0) Nov 2006 or later";
            //3.0.4506.25 yes(WAPRTM.004506 - 0026) Vista Ultimate, Jan 2007
            if ((Major >= 3) && (Minor >= 5) && (Build >= 4506) && (Revision >= 25))
                return @"(WAPRTM.004506 - 0026) Vista Ultimate, Jan 2007 or later";

            //2.0.50727.4927  yes(NetFXspW7.050727 - 4900) / Windows 7 Release, Oct 2009
            if ((Major >=2) && (Minor >=0) && (Build >= 50727) && (Revision >= 4927))
                return @"(NetFXspW7.050727 - 4900) / Windows 7 Release, Oct 2009 or later";
            //2.0.50727.4918(NetFXspW7.050727 - 4900) / Windows 7 Release Candidate, June 2009
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 4918))
                return @"(NetFXspW7.050727 - 4900) / Windows 7 Release Candidate, June 2009 or later";
            //2.0.50727.4200  yes(NetFxQFE.050727 - 4200).NET 2.0 SP2, KB974470, Securityupdate, Oct 2009
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 4200))
                return @"(NetFxQFE.050727 - 4200).NET 2.0 SP2, KB974470, Securityupdate, Oct 2009 or later";
            //2.0.50727.3603(GDR.050727 - 3600).NET 4.0 Beta 2, Oct 2009
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 3603))
                return @"(GDR.050727 - 3600).NET 4.0 Beta 2, Oct 2009 or later";
            //2.0.50727.3082  yes(QFE.050727 - 3000), .NET 3.5 Family Update XP / W2003, Dez 2008, KB958481
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 3082))
                return @"(QFE.050727 - 3000), .NET 3.5 Family Update XP / W2003, Dez 2008, KB958481 or later";
            //2.0.50727.3074  yes(QFE.050727 - 3000), .NET 3.5 Family Update Vista / W2008, Dez 2008, KB958481
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 3074))
                return @"(QFE.050727 - 3000), .NET 3.5 Family Update Vista / W2008, Dez 2008, KB958481 or later";
            //2.0.50727.3053  yes(netfxsp.050727 - 3000), .NET 2.0 SP2, Aug 2008
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 3053))
                return @"yes(netfxsp.050727 - 3000), .NET 2.0 SP2, Aug 2008 or later";
            //2.0.50727.3031(netfxsp.050727 - 3000), .NET 2.0 SP2 Beta 1, May 2008
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 3031))
                return @"(netfxsp.050727 - 3000), .NET 2.0 SP2 Beta 1, May 2008 or later";
            //2.0.50727.1434  yes(REDBITS.050727 - 1400), Windows Server 2008 and Windows Vista SP1, Dez 2007
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 1434))
                return @"(REDBITS.050727 - 1400), Windows Server 2008 and Windows Vista SP1, Dez 2007 or later";
            //2.0.50727.1433  yes(REDBITS.050727 - 1400), .NET 2.0 SP1 Release, Nov 2007, http://www.microsoft.com/downloads/details.aspx?FamilyID=79bc3b77-e02c-4ad3-aacf-a7633f706ba5
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 1433))
                return @"(REDBITS.050727 - 1400), .NET 2.0 SP1 Release, Nov 2007 or later";
            //2.0.50727.1378(REDBITSB2.050727 - 1300), Orcas Beta2, Oct 2007
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 1378))
                return @"(REDBITSB2.050727 - 1300), Orcas Beta2, Oct 2007 or later";
            //2.0.50727.1366(REDBITS.050727 - 1300), Orcas Beta1, Mar 2007
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 1366))
                return @"(REDBITS.050727 - 1300), Orcas Beta1, Mar 2007 or later";
            //2.0.50727.867   yes(VS Express Edition 2005 SP1), Apr 2007, http://www.microsoft.com/downloads/details.aspx?FamilyId=7B0B0339-613A-46E6-AB4D-080D4D4A8C4E
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 867))
                return @"(VS Express Edition 2005 SP1), Apr 2007 or later";
            //2.0.50727.832(Fix x86 VC++2005), Apr 2007, http://support.microsoft.com/kb/934586/en-us
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 832))
                return @"(Fix x86 VC++2005), Apr 2007 or later";
            //2.0.50727.762   yes(VS TeamSuite SP1), http://www.microsoft.com/downloads/details.aspx?FamilyId=BB4A75AB-E2D4-4C96-B39D-37BAF6B5B1DC
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 762))
                return @"(VS TeamSuite SP1) or later";
            //2.0.50727.312   yes(rtmLHS.050727 - 3100) Vista Ultimate, Jan 2007
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 312))
                return @"(rtmLHS.050727 - 3100) Vista Ultimate, Jan 2007 or later";
            //2.0.50727.42    yes Release (.NET Framework 2.0) Oct 2005
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 42))
                return @"Release (.NET Framework 2.0) Oct 2005 or later";
            //2.0.50727.26        Version 2.0(Visual Studio Team System 2005 Release Candidate) Oct 2005
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 26))
                return @"Version 2.0(Visual Studio Team System 2005 Release Candidate) Oct 2005 or later";

            //2.0.50712       Version 2.0(Visual Studio Team System 2005(Drop3) CTP) July 2005
            if ((Major >=2) && (Minor >=0) && (Build >= 50712))
                return @"Version 2.0(Visual Studio Team System 2005(Drop3) CTP) July 2005 or later";
            //2.0.50215       Version 2.0(WinFX SDK for Indigo / Avalon 2005 CTP) July 2005
            if ((Major >=2) && (Minor >=0) && (Build >= 50215))
                return @"Version 2.0(WinFX SDK for Indigo / Avalon 2005 CTP) July 2005 or later";
            //2.0.50601.0     Version 2.0(Visual Studio.NET 2005 CTP) June 2005
            if ((Major >=2) && (Minor >=0) && (Build >= 50601) && (Revision >=0))
                return @"Version 2.0(Visual Studio.NET 2005 CTP) June 2005 or later";
            //2.0.50215.44        Version 2.0(Visual Studio.NET 2005 Beta 2, Visual Studio Express Beta 2) Apr 2005
            if ((Major >=2) && (Minor >=0) && (Build >= 50215) && (Revision >= 44))
                return @"Version 2.0(Visual Studio.NET 2005 Beta 2, Visual Studio Express Beta 2) Apr 2005 or later";
            //2.0.50110.28        Version 2.0(Visual Studio.NET 2005 CTP, Professional Edition) Feb 2005
            if ((Major >=2) && (Minor >=0) && (Build >= 50110) && (Revision >=28))
                return @"Version 2.0(Visual Studio.NET 2005 CTP, Professional Edition) Feb 2005 or later";
            //2.0.41115.19        Version 2.0(Visual Studio.NET 2005 Beta 1, Team System Refresh) Dec 2004
            if ((Major >=2 ) && (Minor >=0 ) && (Build >= 41115) && (Revision >= 19))
                return @"Version 2.0(Visual Studio.NET 2005 Beta 1, Team System Refresh) Dec 2004 or later";
            //2.0.40903.0         Version 2.0(Whidbey CTP, Visual Studio Express) Oct 2004
            if ((Major >=2) && (Minor >=0) && (Build >= 40903) && (Revision >=0))
                return @"Version 2.0(Whidbey CTP, Visual Studio Express) Oct 2004 or later";
            //2.0.40607.85        Version 2.0(Visual Studio.NET 2005 Beta 1, Team System Refresh) Aug 2004 *
            if ((Major >=2) && (Minor >=0) && (Build >= 40607) && (Revision >= 85))
                return @"Version 2.0(Visual Studio.NET 2005 Beta 1, Team System Refresh) Aug 2004 * or later";
            //2.0.40607.42        Version 2.0(SQL Server Yukon Beta 2) July 2004
            if ((Major >=2) && (Minor >=0) && (Build >= 40607) && (Revision >= 42))
                return @"Version 2.0(SQL Server Yukon Beta 2) July 2004 or later";
            //2.0.40607.16        Version 2.0(Visual Studio.NET 2005 Beta 1, TechEd Europe 2004) June 2004
            if ((Major >=2) && (Minor >=0) && (Build >= 40607) && (Revision >= 16))
                return @"Version 2.0(Visual Studio.NET 2005 Beta 1, TechEd Europe 2004) June 2004 or later";
            //2.0.40301.9         Version 2.0(Whidbey CTP, WinHEC 2004) March 2004 *
            if ((Major >=0) && (Minor >=0) && (Build >= 40301) && (Revision >=9))
                return @"Version 2.0(Whidbey CTP, WinHEC 2004) March 2004 * or later";

            //1.2.30703.27        Version 1.2(Whidbey Alpha, PDC 2004) Nov 2003 *
            if ((Major >=1) && (Minor >=2) && (Build >= 30703) && (Revision >= 27))
                return @"Version 1.2(Whidbey Alpha, PDC 2004) Nov 2003 * or later";
            //1.2.21213.1     Version 1.2(Whidbey pre - Alpha build) *
            if ((Major >=1) && (Minor >=2) && (Build >= 21213) && (Revision >=1))
                return @"Version 1.2(Whidbey pre - Alpha build) * or later";

            //1.1.4322.2443   yes Version 1.1 Servicepack 1, KB953297, Oct 2009
            if ((Major >=1) && (Minor >=1) && (Build >= 4322) && (Revision >=2443))
                return @"Version 1.1 Servicepack 1, KB953297, Oct 2009 or later";
            //1.1.4322.2407   yes Version 1.1 RTM
            if ((Major >=1) && (Minor >=1) && (Build >= 4322) && (Revision >= 2407))
                return @"Version 1.1 RTM or later";
            //1.1.4322.2407       Version 1.1 Orcas Beta2, Oct 2007
            if ((Major >=1) && (Minor >=1) && (Build >= 4322) && (Revision >= 2407))
                return @"Version 1.1 Orcas Beta2, Oct 2007 or later";
            //1.1.4322.2379       Version 1.1 Orcas Beta1, Mar 2007
            if ((Major >=1) && (Minor >=1) && (Build >= 4322) && (Revision >= 2379))
                return @"Version 1.1 Orcas Beta1, Mar 2007 or later";
            //1.1.4322.2032   yes Version 1.1 SP1 Aug 2004
            if ((Major >=1) && (Minor >=1) && (Build >= 4322) && (Revision >= 2032))
                return @"Version 1.1 SP1 Aug 2004 or later";
            //1.1.4322.573    yes Version 1.1 RTM(Visual Studio.NET 2003 / Windows Server 2003) Feb 2003 *
            if ((Major >=1) && (Minor >=1) && (Build >= 4322) && (Revision >= 573))
                return @"Version 1.1 RTM(Visual Studio.NET 2003 / Windows Server 2003) Feb 2003 * or later";
            //1.1.4322.510        Version 1.1 Final Beta Oct 2002 *
            if ((Major >=1) && (Minor >=1) && (Build >= 4322) && (Revision >= 510))
                return @"Version 1.1 Final Beta Oct 2002 * or later";

            //1.0.3705.6018   yes Version 1.0 SP3 Aug 2004
            if ((Major >=1) && (Minor >=0) && (Build >= 3705) && (Revision >= 6018))
                return @"Version 1.0 SP3 Aug 2004 or later";
            //1.0.3705.288    yes Version 1.0 SP2 Aug 2002 *
            if ((Major >=1) && (Minor >=0) && (Build >= 3705) && (Revision >= 288))
                return @"Version 1.0 SP2 Aug 2002 * or later";
            //1.0.3705.209    yes Version 1.0 SP1 Mar 2002 *
            if ((Major >=1) && (Minor >=0) && (Build >= 3705) && (Revision >=209))
                return @"Version 1.0 SP1 Mar 2002 * or later";
            //1.0.3705.0  yes Version 1.0 RTM(Visual Studio.NET 2002) Feb 2002 *
            if ((Major >=1) && (Minor >=0) && (Build >= 3705) && (Revision >=0))
                return @"Version 1.0 RTM(Visual Studio.NET 2002) Feb 2002 * or later";
            //1.0.3512.0      Version 1.0 Pre - release RC3(Visual Studio.NET 2002 RC3)
            if ((Major >=1) && (Minor >=0) && (Build >= 3512) && (Revision >=0))
                return @"Version 1.0 Pre - release RC3(Visual Studio.NET 2002 RC3) or later";
            //1.0.2914.16     Version 1.0 Public Beta 2 Jun 2001 *
            if ((Major >=1) && (Minor >=0) && (Build >= 2914) && (Revision >= 16))
                return @"Version 1.0 Public Beta 2 Jun 2001 * or later";
            //1.0.2204.21         Version 1.0 Public Beta 1 Nov 2000 *
            if ((Major >=1) && (Minor >=0) && (Build >= 2204) && (Revision >=21))
                return @"Version 1.0 Public Beta 1 Nov 2000 * or later";

            return @"Unknown .NET version";
        }
    }
}

limit treści do 30000 znaków, cały kod to 34045 znaków. Ta najcięższa część kodu
DARTS

To miłe, ale czy możesz ograniczyć to do czegoś, co pasuje jako jedna odpowiedź?
Flexo

Jednak ta część kodu zapewnia tylko jedną metodę DA.VersionNetFramework.GetVersionDicription ()
DARTS,

Do Twojej wiadomości, zbudowałem to jako aplikację 2.0, wrzuciłem do konsoli i zwraca „2.0.50727.5485” ”w systemie, który ma 4.6, więc wygląda jak Środowisko. Wersja może nie zwracać tego, co jest zainstalowane, a do czego jest używane uruchom aplikację Wygląda na to, że jedynym bezpiecznym sposobem na to jest sprawdzenie rejestru.
P. Roe

A dla NET Framework 4.7 i NET Framework 4.7.1 ?
Kiquenet,

3

Miałem sytuację, w której moja biblioteka klas .NET 4.0 mogła zostać wywołana z zestawów wersji .NET 4.0 lub nowszej.

Określone wywołanie metody działałoby tylko wtedy, gdyby zostało wykonane z zestawu 4.5+.

Aby zdecydować, czy powinienem wywołać metodę, czy nie, potrzebowałem określić bieżącą wersję wykonywanego frameworka i jest to całkiem dobre rozwiązanie

var frameworkName = new System.Runtime.Versioning.FrameworkName(
    AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName
);

if (frameworkName.Version >= new Version(4, 5)) 
{
    // run code
}

Po przejrzeniu wszystkich odpowiedzi, które korzystają z rejestru, uważam, że należy to zaznaczyć jako poprawną odpowiedź na podstawie pierwotnego wniosku. Chciał poznać wersję CLR aktualnie wykonywanego zestawu, a nie maksymalną zainstalowaną wersję, która niekoniecznie jest taka sama. Jedynym zastrzeżeniem do tego rozwiązania jest to, że nie działa w .NET 3.5 lub starszym, ale z przyjemnością używam Environment.Version w takich przypadkach.
Stuart Welch

2

Dziękuję za ten post, który był całkiem przydatny. Musiałem go trochę poprawić, aby sprawdzić, czy istnieje framework 2.0, ponieważ klucza rejestru nie można od razu przekonwertować na podwójny. Oto kod:

string[] version_names = rk.GetSubKeyNames();
//version names start with 'v', eg, 'v3.5'
//we also need to take care of strings like v2.0.50727...
string sCurrent = version_names[version_names.Length - 1].Remove(0, 1);
if (sCurrent.LastIndexOf(".") > 1)
{
    string[] sSplit = sCurrent.Split('.');
    sCurrent = sSplit[0] + "." + sSplit[1] + sSplit[2];
}
double dCurrent = Convert.ToDouble(sCurrent, System.Globalization.CultureInfo.InvariantCulture);
double dExpected = Convert.ToDouble(sExpectedVersion);
if (dCurrent >= dExpected)

3
Naprawdę nie powinieneś przechowywać numerów wersji w podwójnych. Są podatne na zaokrąglanie. Użyj liczby dziesiętnej.
Instance Hunter

2
public class DA {
  public static class VersionNetFramework {
    public static string Get45or451FromRegistry()
    {//https://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx
        using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\"))
        {
            int releaseKey = Convert.ToInt32(ndpKey.GetValue("Release"));
            if (true)
            {
                return (@"Version: " + CheckFor45DotVersion(releaseKey));
            }
        }
    }
    // Checking the version using >= will enable forward compatibility, 
    // however you should always compile your code on newer versions of
    // the framework to ensure your app works the same.
    private static string CheckFor45DotVersion(int releaseKey)
    {//https://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx
        if (releaseKey >= 394271)
            return "4.6.1 installed on all other Windows OS versions or later";
        if (releaseKey >= 394254)
            return "4.6.1 installed on Windows 10 or later";
        if (releaseKey >= 393297)
            return "4.6 installed on all other Windows OS versions or later";
        if (releaseKey >= 393295)
            return "4.6 installed with Windows 10 or later";
        if (releaseKey >= 379893)
            return "4.5.2 or later";
        if (releaseKey >= 378758)
            return "4.5.1 installed on Windows 8, Windows 7 SP1, or Windows Vista SP2 or later";
        if (releaseKey >= 378675)
            return "4.5.1 installed with Windows 8.1 or later";
        if (releaseKey >= 378389)
            return "4.5 or later";

        return "No 4.5 or later version detected";
    }
    public static string GetVersionFromRegistry()
    {//https://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx
        string res = @"";
        // Opens the registry key for the .NET Framework entry.
        using (RegistryKey ndpKey =
            RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "").
            OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
        {
            // As an alternative, if you know the computers you will query are running .NET Framework 4.5 
            // or later, you can use:
            // using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, 
            // RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
            foreach (string versionKeyName in ndpKey.GetSubKeyNames())
            {
                if (versionKeyName.StartsWith("v"))
                {

                    RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
                    string name = (string)versionKey.GetValue("Version", "");
                    string sp = versionKey.GetValue("SP", "").ToString();
                    string install = versionKey.GetValue("Install", "").ToString();
                    if (install == "") //no install info, must be later.
                        res += (versionKeyName + "  " + name) + Environment.NewLine;
                    else
                    {
                        if (sp != "" && install == "1")
                        {
                            res += (versionKeyName + "  " + name + "  SP" + sp) + Environment.NewLine;
                        }

                    }
                    if (name != "")
                    {
                        continue;
                    }
                    foreach (string subKeyName in versionKey.GetSubKeyNames())
                    {
                        RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
                        name = (string)subKey.GetValue("Version", "");
                        if (name != "")
                            sp = subKey.GetValue("SP", "").ToString();
                        install = subKey.GetValue("Install", "").ToString();
                        if (install == "") //no install info, must be later.
                            res += (versionKeyName + "  " + name) + Environment.NewLine;
                        else
                        {
                            if (sp != "" && install == "1")
                            {
                                res += ("  " + subKeyName + "  " + name + "  SP" + sp) + Environment.NewLine;
                            }
                            else if (install == "1")
                            {
                                res += ("  " + subKeyName + "  " + name) + Environment.NewLine;
                            }
                        }
                    }
                }
            }
        }
        return res;
    }
    public static string GetUpdateHistory()
    {//https://msdn.microsoft.com/en-us/library/hh925567(v=vs.110).aspx
        string res=@"";
        using (RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\Updates"))
        {
            foreach (string baseKeyName in baseKey.GetSubKeyNames())
            {
                if (baseKeyName.Contains(".NET Framework") || baseKeyName.StartsWith("KB") || baseKeyName.Contains(".NETFramework"))
                {

                    using (RegistryKey updateKey = baseKey.OpenSubKey(baseKeyName))
                    {
                        string name = (string)updateKey.GetValue("PackageName", "");
                        res += baseKeyName + "  " + name + Environment.NewLine;
                        foreach (string kbKeyName in updateKey.GetSubKeyNames())
                        {
                            using (RegistryKey kbKey = updateKey.OpenSubKey(kbKeyName))
                            {
                                name = (string)kbKey.GetValue("PackageName", "");
                                res += ("  " + kbKeyName + "  " + name) + Environment.NewLine;

                                if (kbKey.SubKeyCount > 0)
                                {
                                    foreach (string sbKeyName in kbKey.GetSubKeyNames())
                                    {
                                        using (RegistryKey sbSubKey = kbKey.OpenSubKey(sbKeyName))
                                        {
                                            name = (string)sbSubKey.GetValue("PackageName", "");
                                            if (name == "")
                                                name = (string)sbSubKey.GetValue("Description", "");
                                            res += ("    " + sbKeyName + "  " + name) + Environment.NewLine;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return res;
    }
}

przy użyciu klasy DA.VersionNetFramework

private void Form1_Shown(object sender, EventArgs e)
{
    //
    // Current OS Information
    //
    richTextBox1.Text = @"Current OS Information:";
    richTextBox1.AppendText(Environment.NewLine +
                            "Machine Name: " + Environment.MachineName);
    richTextBox1.AppendText(Environment.NewLine +
                            "Platform: " + Environment.OSVersion.Platform.ToString());
    richTextBox1.AppendText(Environment.NewLine +
                            Environment.OSVersion);
    //
    // .NET Framework Environment Information
    //
    richTextBox1.AppendText(Environment.NewLine + Environment.NewLine +
                                       ".NET Framework Environment Information:");
    richTextBox1.AppendText(Environment.NewLine +
                            "Environment.Version " + Environment.Version);
    richTextBox1.AppendText(Environment.NewLine + 
                            DA.VersionNetFramework.GetVersionDicription());
    //
    // .NET Framework Information From Registry
    //
    richTextBox1.AppendText(Environment.NewLine + Environment.NewLine +
                                       ".NET Framework Information From Registry:");
    richTextBox1.AppendText(Environment.NewLine +
                            DA.VersionNetFramework.GetVersionFromRegistry());
    //
    // .NET Framework 4.5 or later Information From Registry
    //
    richTextBox1.AppendText(Environment.NewLine + 
                                       ".NET Framework 4.5 or later Information From Registry:");
    richTextBox1.AppendText(Environment.NewLine +
                            DA.VersionNetFramework.Get45or451FromRegistry());
    //
    // Update History
    //
    richTextBox1.AppendText(Environment.NewLine + Environment.NewLine +
                            "Update History");
    richTextBox1.AppendText(Environment.NewLine + 
                            DA.VersionNetFramework.GetUpdateHistory());
    //
    // Setting Cursor to first character of textbox
    //
    if (!richTextBox1.Text.Equals(""))
    {
        richTextBox1.SelectionStart = 1;
    }
}

Wynik:

Bieżące informacje o systemie operacyjnym: Nazwa komputera: D1 Platforma: Win32NT Microsoft Windows NT 6.2.9200.0

Informacje o środowisku .NET Framework: Environment.Version 4.0.30319.42000 .NET 4.6 w systemie Windows 8.1 w wersji 64-bitowej lub nowszej

Informacje z rejestru .NET Framework: wersja 2.0.50727 2.0.50727.4927 SP2 wersja 3.0.30729.4926 SP2 wersja 3.5 3.5.30729.4926 SP1


Klient v4 4.6.00079 Pełny 4.6.00079
Klient v4.0 4.0.0.0

.NET Framework 4.5 lub nowszy Informacje z rejestru: Wersja: 4.6 zainstalowana z systemem Windows 10 lub nowszym

Historia aktualizacji Microsoft .NET Framework 4 Client Profile
KB2468871
KB2468871v2
KB2478063
KB2533523
KB2544514
KB2600211
KB2600217
Microsoft .NET Framework 4 Extended
KB2468871
KB2468871v2
KB2478063
KB2533523
KB2544514
KB2600211
KB2600217
Microsoft .NET Framework 4 Multi-
37


limit treści do 30000 znaków, cały kod to 34045 znaków, ta najlżejsza część kodu
DARTS

A dla NET Framework 4.7 i NET Framework 4.7.1 ?
Kiquenet,

2

Zmieniłem klasę Matta, aby można go było ponownie wykorzystać w dowolnym projekcie bez drukowania wszystkich sprawdzeń na konsoli i zwracania prostego ciągu znaków z zainstalowaną poprawną wersją max.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;

namespace MyNamespace
{
    public class DotNetVersion
    {
        protected bool printVerification;

        public DotNetVersion(){
            this.printVerification=false;
        }
        public DotNetVersion(bool printVerification){
            this.printVerification=printVerification;
        }


        public string getDotNetVersion(){
            string maxDotNetVersion = getVersionFromRegistry();
            if(String.Compare(maxDotNetVersion, "4.5") >= 0){
                string v45Plus = get45PlusFromRegistry();
                if(!string.IsNullOrWhiteSpace(v45Plus)) maxDotNetVersion = v45Plus;
            }
            log("*** Maximum .NET version number found is: " + maxDotNetVersion + "***");

            return maxDotNetVersion;
        }

        protected string get45PlusFromRegistry(){
            String dotNetVersion = "";
            const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\";
            using(RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey)){
                if(ndpKey != null && ndpKey.GetValue("Release") != null){
                    dotNetVersion = checkFor45PlusVersion((int)ndpKey.GetValue("Release"));
                    log(".NET Framework Version: " + dotNetVersion);
                }else{
                    log(".NET Framework Version 4.5 or later is not detected.");
                }
            }
            return dotNetVersion;
        }

        // Checking the version using >= will enable forward compatibility.
        protected string checkFor45PlusVersion(int releaseKey){
            if(releaseKey >= 461308) return "4.7.1 or later";
            if(releaseKey >= 460798) return "4.7";
            if(releaseKey >= 394802) return "4.6.2";
            if(releaseKey >= 394254) return "4.6.1";
            if(releaseKey >= 393295) return "4.6";
            if((releaseKey >= 379893)) return "4.5.2";
            if((releaseKey >= 378675)) return "4.5.1";
            if((releaseKey >= 378389)) return "4.5";

            // This code should never execute. A non-null release key should mean
            // that 4.5 or later is installed.
            log("No 4.5 or later version detected");
            return "";
        }

        protected string getVersionFromRegistry(){
            String maxDotNetVersion = "";
            // Opens the registry key for the .NET Framework entry.
            using(RegistryKey ndpKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "")
                                            .OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\")){
                // As an alternative, if you know the computers you will query are running .NET Framework 4.5 
                // or later, you can use:
                // using(RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, 
                // RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
                string[] subKeyNnames = ndpKey.GetSubKeyNames();
                foreach(string versionKeyName in subKeyNnames){
                    if(versionKeyName.StartsWith("v")){
                        RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
                        string name =(string)versionKey.GetValue("Version", "");
                        string sp = versionKey.GetValue("SP", "").ToString();
                        string install = versionKey.GetValue("Install", "").ToString();
                        if(string.IsNullOrWhiteSpace(install)){ //no install info, must be later.
                            log(versionKeyName + "  " + name);
                            if(String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                        }else{
                            if(!string.IsNullOrWhiteSpace(sp) && "1".Equals(install)){
                                log(versionKeyName + "  " + name + "  SP" + sp);
                                if(String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                            }

                        }
                        if(!string.IsNullOrWhiteSpace(name)){
                            continue;
                        }

                        string[] subKeyNames = versionKey.GetSubKeyNames();
                        foreach(string subKeyName in subKeyNames){
                            RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
                            name =(string)subKey.GetValue("Version", "");
                            if(!string.IsNullOrWhiteSpace(name)){
                                sp = subKey.GetValue("SP", "").ToString();
                            }
                            install = subKey.GetValue("Install", "").ToString();
                            if(string.IsNullOrWhiteSpace(install)){
                                //no install info, must be later.
                                log(versionKeyName + "  " + name);
                                if(String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                            }else{
                                if(!string.IsNullOrWhiteSpace(sp) && "1".Equals(install)){
                                    log("  " + subKeyName + "  " + name + "  SP" + sp);
                                    if(String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                                }
                                else if("1".Equals(install)){
                                    log("  " + subKeyName + "  " + name);
                                    if(String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                                } // if
                            } // if
                        } // for
                    } // if
                } // foreach
            } // using
            return maxDotNetVersion;
        }

        protected void log(string message){
            if(printVerification) Console.WriteLine(message);
        }

    } // class
}

2

Starałem się połączyć wszystkie odpowiedzi w jedną całość.

Za pomocą:

NetFrameworkUtilities.GetVersion()zwróci aktualnie dostępną wersję programu .NET Framework lub wartość null, jeśli nie jest obecna.

Ten przykład działa w .NET Framework w wersji 3.5+. Nie wymaga uprawnień administratora.

Chcę zauważyć, że możesz sprawdzić wersję za pomocą operatorów <i> w ten sposób:

var version = NetFrameworkUtilities.GetVersion();
if (version != null && version < new Version(4, 5))
{
    MessageBox.Show("Your .NET Framework version is less than 4.5");
}

Kod:

using System;
using System.Linq;
using Microsoft.Win32;

namespace Utilities
{
    public static class NetFrameworkUtilities
    {
        public static Version GetVersion() => GetVersionHigher4() ?? GetVersionLowerOr4();

        private static Version GetVersionLowerOr4()
        {
            using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP"))
            {
                var names = key?.GetSubKeyNames();

                //version names start with 'v', eg, 'v3.5' which needs to be trimmed off before conversion
                var text = names?.LastOrDefault()?.Remove(0, 1);
                if (string.IsNullOrEmpty(text))
                {
                    return null;
                }

                return text.Contains('.')
                    ? new Version(text)
                    : new Version(Convert.ToInt32(text), 0);
            }
        }

        private static Version GetVersionHigher4()
        {
            using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"))
            {
                var value = key?.GetValue("Release");
                if (value == null)
                {
                    return null;
                }

                // Checking the version using >= will enable forward compatibility,  
                // however you should always compile your code on newer versions of 
                // the framework to ensure your app works the same. 
                var releaseKey = Convert.ToInt32(value);
                if (releaseKey >= 461308) return new Version(4, 7, 1);
                if (releaseKey >= 460798) return new Version(4, 7);
                if (releaseKey >= 394747) return new Version(4, 6, 2);
                if (releaseKey >= 394254) return new Version(4, 6, 1);
                if (releaseKey >= 381029) return new Version(4, 6);
                if (releaseKey >= 379893) return new Version(4, 5, 2);
                if (releaseKey >= 378675) return new Version(4, 5, 1);
                if (releaseKey >= 378389) return new Version(4, 5);

                // This line should never execute. A non-null release key should mean 
                // that 4.5 or later is installed. 
                return new Version(4, 5);
            }
        }
    }
}

1

Zaktualizuj za pomocą .NET 4.6.2. Sprawdź wartość wydania w tym samym rejestrze, co w poprzednich odpowiedziach:

RegistryKey registry_key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full");
if (registry_key == null)
    return false;
var val = registry_key.GetValue("Release", 0);
UInt32 Release = Convert.ToUInt32(val);

if (Release >= 394806) // 4.6.2 installed on all other Windows (different than Windows 10)
                return true;
if (Release >= 394802) // 4.6.2 installed on Windows 10 or later
                return true;

A updatesdla NET Framework 4.7 i NET Framework 4.7.1 ?
Kiquenet,

0

Trochę duży, ale wygląda na to, że zawiera aktualne informacje o osobliwościach Microsoftu:

    public static class Versions
    {
        static Version 
            _NET;

        static SortedList<String,Version>
            _NETInstalled;

#if NET40
#else
        public static bool VersionTry(String S, out Version V)
        {
            try
            { 
                V=new Version(S); 
                return true;
            }
            catch
            {
                V=null;
                return false;
            }
        }
#endif
        const string _NetFrameWorkKey = "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP";
        static void FillNetInstalled()
        {
            if (_NETInstalled == null)
            {
                _NETInstalled = new SortedList<String, Version>(StringComparer.InvariantCultureIgnoreCase);
                RegistryKey
                    frmks = Registry.LocalMachine.OpenSubKey(_NetFrameWorkKey);
                string[]
                    names = frmks.GetSubKeyNames();
                foreach (string name in names)
                {
                    if (name.StartsWith("v", StringComparison.InvariantCultureIgnoreCase) && name.Length > 1)
                    {
                        string
                            f, vs;
                        Version
                            v;
                        vs = name.Substring(1);
                        if (vs.IndexOf('.') < 0)
                            vs += ".0";
#if NET40
                        if (Version.TryParse(vs, out v))
#else
                        if (VersionTry(vs, out v))
#endif
                        {
                            f = String.Format("{0}.{1}", v.Major, v.Minor);
#if NET40
                            if (Version.TryParse((string)frmks.OpenSubKey(name).GetValue("Version"), out v))
#else
                            if (VersionTry((string)frmks.OpenSubKey(name).GetValue("Version"), out v))
#endif
                            {
                                if (!_NETInstalled.ContainsKey(f) || v.CompareTo(_NETInstalled[f]) > 0)
                                    _NETInstalled[f] = v;
                            }
                            else
                            { // parse variants
                                Version
                                    best = null;
                                if (_NETInstalled.ContainsKey(f))
                                    best = _NETInstalled[f];
                                string[]
                                    varieties = frmks.OpenSubKey(name).GetSubKeyNames();
                                foreach (string variety in varieties)
#if NET40
                                    if (Version.TryParse((string)frmks.OpenSubKey(name + '\\' + variety).GetValue("Version"), out v))
#else
                                    if (VersionTry((string)frmks.OpenSubKey(name + '\\' + variety).GetValue("Version"), out v))
#endif
                                    {
                                        if (best == null || v.CompareTo(best) > 0)
                                        {
                                            _NETInstalled[f] = v;
                                            best = v;
                                        }
                                        vs = f + '.' + variety;
                                        if (!_NETInstalled.ContainsKey(vs) || v.CompareTo(_NETInstalled[vs]) > 0)
                                            _NETInstalled[vs] = v;
                                    }
                            }
                        }
                    }
                }
            }
        } // static void FillNetInstalled()

        public static Version NETInstalled
        {
            get
            {
                FillNetInstalled();
                return _NETInstalled[_NETInstalled.Keys[_NETInstalled.Count-1]];
            }
        } // NETInstalled

        public static Version NET
        {
            get
            {
                FillNetInstalled();
                string
                    clr = String.Format("{0}.{1}", Environment.Version.Major, Environment.Version.Minor);
                Version
                    found = _NETInstalled[_NETInstalled.Keys[_NETInstalled.Count-1]];
                if(_NETInstalled.ContainsKey(clr))
                    return _NETInstalled[clr];

                for (int i = _NETInstalled.Count - 1; i >= 0; i--)
                    if (_NETInstalled.Keys[i].CompareTo(clr) < 0)
                        return found;
                    else
                        found = _NETInstalled[_NETInstalled.Keys[i]];
                return found;
            }
        } // NET
    }

0

Począwszy od wersji 4.5 Microsoft zmienił sposób przechowywania wskaźnika .NET Framework w rejestrze. Oficjalne wskazówki dotyczące pobierania platformy .NET i wersji CLR można znaleźć tutaj: https://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx

Załączam zmodyfikowaną wersję ich kodu, aby odpowiedzieć na pytanie, w jaki sposób określasz strukturę .NET dla 4.5 i nowszych tutaj:

using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32;

namespace stackoverflowtesting
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<int, String> mappings = new Dictionary<int, string>();

            mappings[378389] = "4.5";
            mappings[378675] = "4.5.1 on Windows 8.1";
            mappings[378758] = "4.5.1 on Windows 8, Windows 7 SP1, and Vista";
            mappings[379893] = "4.5.2";
            mappings[393295] = "4.6 on Windows 10";
            mappings[393297] = "4.6 on Windows not 10";

            using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\"))
            {
                int releaseKey = Convert.ToInt32(ndpKey.GetValue("Release"));
                if (true)
                {
                    Console.WriteLine("Version: " + mappings[releaseKey]);
                }
            }
            int a = Console.Read();
        }
    }
}

A updatesdla NET Framework 4.7 i NET Framework 4.7.1 ?
Kiquenet,

0

Oto rozwiązanie, na którym wylądowałem:

private static string GetDotNetVersion()
{
  var v4 = (string)Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full", false)?.GetValue("Version");
  if(v4 != null)
    return v4;
  var v35 = (string)Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5", false)?.GetValue("Version");
  if(v35 != null)
    return v35;
  var v3 = (string)Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.0", false)?.GetValue("Version");
  return v3 ?? "< 3";
}

0
        public static class DotNetHelper
{
    public static Version InstalledVersion
    {
        get
        {
            string framework = null;

            try
            {
                using (var ndpKey =
            Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\"))
                {
                    if (ndpKey != null)
                    {
                        var releaseKey = ndpKey.GetValue("Release");
                        if (releaseKey != null)
                        {
                            framework = CheckFor45PlusVersion(Convert.ToInt32(releaseKey));
                        }
                        else
                        {
                            string[] versionNames = null;
                            using (var installedVersions =
                                Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP"))
                            {
                                if (installedVersions != null) versionNames = installedVersions.GetSubKeyNames();
                            }


                            try
                            {
                                if (versionNames != null && versionNames.Length > 0)
                                {
                                    framework = versionNames[versionNames.Length - 1].Remove(0, 1);
                                }
                            }
                            catch (FormatException)
                            {

                            }
                        }
                    }
                }
            }
            catch (SecurityException)
            {
            }

            return framework != null ? new Version(framework) : null;
        }
    }

    private static string CheckFor45PlusVersion(int releaseKey)
    {
        if (releaseKey >= 460798)
            return "4.7";
        if (releaseKey >= 394802)
            return "4.6.2";
        if (releaseKey >= 394254)
            return "4.6.1";
        if (releaseKey >= 393295)
            return "4.6";
        if (releaseKey >= 379893)
            return "4.5.2";
        if (releaseKey >= 378675)
            return "4.5.1";
        // This code should never execute. A non-null release key should mean
        // that 4.5 or later is installed.
        return releaseKey >= 378389 ? "4.5" : null;
    }
}

A updatesdla NET Framework 4.7 i NET Framework 4.7.1 ?
Kiquenet,

0

Jeśli twój komputer jest podłączony do Internetu, prawdopodobnie najłatwiejszym sposobem jest przejście do najmniejszego dotnetu , pobranie i uruchomienie narzędzia .NET Checker.

Jeśli potrzebujesz właściwej metody określenia wersji, spójrz na jej źródło na github, zwł. z Constants.cs które pomogą Ci NET 4.5 i nowszym, gdzie część Weryfikacja jest relvant jeden:

                           { int.MinValue, "4.5" },
                           { 378389, "4.5" },
                           { 378675, "4.5.1" },
                           { 378758, "4.5.1" },
                           { 379893, "4.5.2" },
                           { 381029, "4.6 Preview" },
                           { 393273, "4.6 RC1" },
                           { 393292, "4.6 RC2" },
                           { 393295, "4.6" },
                           { 393297, "4.6" },
                           { 394254, "4.6.1" },
                           { 394271, "4.6.1" },
                           { 394747, "4.6.2 Preview" },
                           { 394748, "4.6.2 Preview" },
                           { 394757, "4.6.2 Preview" },
                           { 394802, "4.6.2" },
                           { 394806, "4.6.2" },

A updatesdla NET Framework 4.7 i NET Framework 4.7.1 ?
Kiquenet

@Kiquenet Niestety 4.7 i 4.7.1 nie są zawarte w kodzie źródłowym, ale są problemy z kluczami zwalniającymi , których możesz użyć - i / lub sam podaj żądanie ściągnięcia ;-)
mbx

PS: zanim zainwestujesz ten czas w pull request, wiedz, że przez jakiś czas jest w przygotowaniu przynajmniej jeden PR - myślę, że Scott był ostatnio zbyt zajęty.
mbx

0

Łatwiej mi pracuje z Versionklasą:

using Microsoft.Win32;
using System.Runtime.InteropServices;

namespace System.Runtime.InteropServices {
  public static class RuntimeInformationEx {

    public static Version? GetDotnetFrameworkVersion() {
      using var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full");
      if (key is object) {
        if (!Int32.TryParse(key.GetValue("Release", "").ToString(), out var release)) return null;
        return release switch
        {
          378389 => new Version(4, 5, 0),
          378675 => new Version(4, 5, 1),
          378758 => new Version(4, 5, 1),
          379893 => new Version(4, 5, 2),
          393295 => new Version(4, 6, 0),
          393297 => new Version(4, 6, 0),
          394254 => new Version(4, 6, 1),
          394271 => new Version(4, 6, 1),
          394802 => new Version(4, 6, 2),
          394806 => new Version(4, 6, 2),
          460798 => new Version(4, 7, 0),
          460805 => new Version(4, 7, 0),
          461308 => new Version(4, 7, 1),
          461310 => new Version(4, 7, 1),
          461808 => new Version(4, 7, 2),
          461814 => new Version(4, 7, 2),
          528040 => new Version(4, 8, 0),
          528209 => new Version(4, 8, 0),
          528049 => new Version(4, 8, 0),
          _ => null
        };

      } else { // .NET version < 4.5
        using var key1 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP");
        if (key1 is null) return null;
        var parts = key1.GetSubKeyNames()[^1].Substring(1).Split('.'); // get lastsub key, remove 'v' prefix, and split
        if (parts.Length == 2) parts = new string[] { parts[0], parts[1], "0" };
        if (parts.Length != 3) return null;
        Func<string, int> Parse = s => Int32.TryParse(s, out var i) ? i : -1;
        try { return new Version(Parse(parts[0]), Parse(parts[1]), Parse(parts[2])); } catch { return null; }
      }
    }

    public static Version? GetDotnetCoreVersion() {
      if (!RuntimeInformation.FrameworkDescription.StartsWith(".NET Core ")) return null;
      var parts = RuntimeInformation.FrameworkDescription.Substring(10).Split('.');
      if (parts.Length == 2) parts = new string[] { parts[0], parts[1], "0" };
      if (parts.Length != 3) return null;
      Func<string, int> Parse = s => Int32.TryParse(s, out var i) ? i : -1;
      try { return new Version(Parse(parts[0]), Parse(parts[1]), Parse(parts[2])); } catch { return null; }
    }
  }
}

(kod to C # 8)


1
Ta odpowiedź sprzed dwóch lat dokonuje już mapowania "Release"wartości na Versions. Myślę, że kluczowy punkt, w którym te informacje są przechowywane w rejestrze i w jakim formacie, jest dobrze udokumentowany tutaj; czy to przedstawiane jako rozmówcy string, int, enumczy Versionwszystko jest tylko wprowadzenie innego opakowania na tej samej rzeczy.
BACON

tak, o ile widzę, moja odpowiedź działa tak samo jak ta, ale ma wszystkie wersje .NET w jednej funkcji .. użycie wersji umożliwia łatwe porównania itp. np.var v=RuntimeInformationEx .GetDotnetFrameworkVersion(); if (v<new Version(4,8,0) ...
kofifus

0

Możesz uzyskać przydatny ciąg bez konieczności dotykania rejestru lub zestawów odwołań, które mogą być ładowane lub nie. mscorlib.dll i inne zestawy systemowe mają zdefiniowany AssemblyFileVersionAttribute i wydaje się być unikatowy dla każdej wersji .NET, na podstawie zestawów referencyjnych dostarczonych z programem Visual Studio.

string version = (typeof(string).Assembly
    .GetCustomAttributes(typeof(AssemblyFileVersionAttribute), false)
    .FirstOrDefault() as AssemblyFileVersionAttribute)?.Version;

Wersja 4.5 jest trochę nieaktualna, ponieważ jest oznaczona jako 4.0 w tej wersji, ale od wersji 4.6 wydaje się, że wersja pomocnicza pasuje co najmniej. Zrobienie tego w ten sposób wydaje się być bardziej przyszłościowe niż uzależnienie od klucza rejestru instalatora i konieczność porównania z ustalonym zestawem wartości.

Znalazłem tutaj zestawy referencyjne:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework

Skąd mam następujące wersje:

4.0 = 4.0.30319.1
4.5 = 4.0.30319.18020
4.5.1 = 4.0.30319.18402
4.5.2 = 4.0.30319.34211
4.6 = 4.6.81.0
4.6.1 = 4.6.1055.0
4.7.2 = 4.7.3062.0
4.8 = 4.8.3761.0

-1

Spróbuj tego:

string GetFrameWorkVersion()
    {
        return System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion();
    }

2
To daje, 2.0nawet jeśli działa z3.5
LCJ

RuntimeEnvironment.GetSystemVersion()wydaje się, że zwraca wersję CLR, a nie wersję .NET. Strona MSDN
marchica
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.