Jak wykryć, które wersje .NET Framework i dodatki Service Pack są zainstalowane?

289

Podobne pytanie zostało zadane tutaj , ale dotyczyło .NET 3.5. W szczególności szukam następujących rzeczy:

  1. Jaki jest prawidłowy sposób ustalenia, które wersje .NET Framework i dodatki Service Pack są zainstalowane?
  2. Czy istnieje lista kluczy rejestru, których można użyć?
  3. Czy są jakieś zależności między wersjami Framework?
Scott Dorman
źródło
2
To pytanie jest ściśle związane z stackoverflow.com/questions/198931/... i stackoverflow.com/questions/182910/…
Pascal Paradis
Tak to jest. Wiedziałem już o pierwszym (do tego, o którym mówię w moim pytaniu). Nie wiedziałem o drugim.
Scott Dorman
3
Jestem pod wrażeniem, jak to pytanie (łącznie z odpowiedziami) i wszystkie ściśle powiązane pytania całkowicie ignorują obecność wartości SKU - to nawet rozróżnia między 4.5 a 4.5.1.
springy76
@ springy76, Powodem, dla którego nie dotyczy to obecności wartości SKU, jest to, że do celów ustalenia, które wersje środowiska są zainstalowane, nie są one istotne. Pytanie, na które się powołujesz, próbuje ustalić, czy „.NET 4.0.2” jest zainstalowany. Problem polega na tym, że nie było .NET 4.0.2, była to aktualizacja (KB2544514), a nie wydanie Framework lub dodatek Service Pack. Możesz przeczytać ten artykuł w witrynie MSDN ( msdn.microsoft.com/en-us/library/hh925567(v=vs.110).aspx ), aby uzyskać więcej informacji na temat wykrywania zainstalowanych aktualizacji.
Scott Dorman

Odpowiedzi:

365

Rejestr jest oficjalnym sposobem wykrywania, czy zainstalowana jest konkretna wersja Framework.

wprowadź opis zdjęcia tutaj

Które klucze rejestru są potrzebne, zmieniaj się w zależności od wersji Framework, której szukasz:

Klucz rejestru w wersji Framework
-------------------------------------------------- ----------------------------------------
1.0 HKLM \ Software \ Microsoft \ .NETFramework \ Policy \ v1.0 \ 3705 
1.1 HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v1.1.4322 \ Install 
2.0 HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v2.0.50727 \ Install 
3.0 HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v3.0 \ Setup \ InstallSuccess 
3.5 HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v3.5 \ Install 
4.0 Profil klienta HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v4 \ Client \ Install
4.0 Pełny profil HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v4 \ Full \ Install

Na ogół szukasz:

"Install"=dword:00000001

z wyjątkiem .NET 1.0, gdzie wartością jest string ( REG_SZ) zamiast number ( REG_DWORD).

Określanie poziomu dodatku Service Pack odbywa się w podobny sposób:

Klucz rejestru w wersji Framework
-------------------------------------------------- ----------------------------------------
1.0 HKLM \ Software \ Microsoft \ Active Setup \ Installed Components \ {78705f0d-e8db-4b2d-8193-982bdda15ecd} \ Wersja 
1.0 [1] HKLM \ Software \ Microsoft \ Active Setup \ Installed Components \ {FDC11A6F-17D1-48f9-9EA3-9051954BAA24} \ Wersja 
1.1 HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v1.1.4322 \ SP 
2.0 HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v2.0.50727 \ SP 
3.0 HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v3.0 \ SP 
3.5 HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v3.5 \ SP 
4.0 Profil klienta HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v4 \ Client \ Servicing
4.0 Pełny profil HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v4 \ Full \ Servicing

[1] Windows Media Center lub Windows XP Tablet Edition

Jak widać, określanie poziomu SP dla zmian .NET 1.0 zmienia się, jeśli używasz Windows Media Center lub Windows XP Tablet Edition. Ponownie .NET 1.0 używa wartości ciągu, podczas gdy wszystkie inne używają DWORD.

W przypadku .NET 1.0 wartość ciągu w jednym z tych kluczy ma format #, #, ####, #. Ostatni # to poziom dodatku Service Pack.

Chociaż nie prosiłem o to wyraźnie, jeśli chcesz znać dokładny numer wersji środowiska, możesz użyć tych kluczy rejestru:

Klucz rejestru w wersji Framework
-------------------------------------------------- ----------------------------------------
1.0 HKLM \ Software \ Microsoft \ Active Setup \ Installed Components \ {78705f0d-e8db-4b2d-8193-982bdda15ecd} \ Wersja 
1.0 [1] HKLM \ Software \ Microsoft \ Active Setup \ Installed Components \ {FDC11A6F-17D1-48f9-9EA3-9051954BAA24} \ Wersja 
1.1 HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v1.1.4322 
2.0 [2] HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v2.0.50727 \ Version 
2.0 [3] HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v2.0.50727 \ Przyrost
3.0 HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v3.0 \ Version 
3.5 HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v3.5 \ Version 
4.0 Profil klienta HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v4 \ Version 
4.0 Pełny profil HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v4 \ Version 

[1] Windows Media Center lub Windows XP Tablet Edition
[2] .NET 2.0 SP1
[3] .NET 2.0 Original Release (RTM)

Ponownie .NET 1.0 używa wartości ciągu, podczas gdy wszystkie inne używają DWORD.

Dodatkowe uwagi

  • dla .NET 1.0 wartość ciągu w jednym z tych kluczy ma format #,#,####,#. #,#,####Część napisu jest wersja Framework.

  • w przypadku .NET 1.1 używamy samej nazwy klucza rejestru, która reprezentuje numer wersji.

  • Na koniec, jeśli spojrzysz na zależności, .NET 3.0 dodaje dodatkową funkcjonalność do .NET 2.0, więc zarówno .NET 2.0, jak i .NET 3.0 muszą ewaluować jako zainstalowane, aby poprawnie powiedzieć, że .NET 3.0 jest zainstalowany. Podobnie .NET 3.5 dodaje dodatkowe funkcje do .NET 2.0 i .NET 3.0, więc .NET 2.0, .NET 3.0 i .NET 3. powinny ocenić, czy są zainstalowane, aby poprawnie powiedzieć, że .NET 3.5 jest zainstalowany.

  • .NET 4.0 instaluje nową wersję CLR (CLR wersja 4.0), która może działać równolegle z CLR 2.0.

Aktualizacja dla .NET 4.5

W v4.5rejestrze .NET 4.5 nie będzie klucza. Zamiast tego musisz sprawdzić, czy HKLM\Software\Microsoft\NET Framework Setup\NDP\v4\Fullklucz zawiera wartość o nazwie Release. Jeśli ta wartość jest obecna, to .NET 4.5 jest zainstalowany, w przeciwnym razie nie będzie. Więcej informacji można znaleźć tutaj i tutaj .

Scott Dorman
źródło
1
To nie wydaje się działać w przypadku .NET 1.1 w systemie Vista x64. Żadne klucze v1.1.x nie znajdują się w żadnym z możliwych miejsc. Pomysły?
Chris Hynes,
7
Klucze .NET 4.0 nie są całkiem poprawne. Widzę te klucze: HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v4 \ Client \ Install HKLM \ Software \ Microsoft \ NET Framework Setup \ NDP \ v4 \ Full \ Install Folder v4.0 ma tylko jeden klucz , (Domyślnie) z wartością nieaktualną.
RandomEngy
2
Ten post nie obejmuje wersji 4.5, a wersja 4.5 nie jest wymieniona w rejestrze, nawet jeśli jest zainstalowana.
Klas Mellbourn,
37
Człowieku, czy nikt w Microsoft nie pomyślał o dodaniu przełącznika -wersji?
gnuchu
2
To żart. Nie mogę uwierzyć, że to takie głupie!
Alex Byrth,
17

Oficjalna odpowiedź Microsoft na to pytanie znajduje się w następującym artykule bazy wiedzy:

Identyfikator artykułu: 318785 - Ostatni przegląd: 7 listopada 2008 r. - Wersja: 20.1 Jak ustalić, które wersje systemu .NET Framework są zainstalowane i czy zastosowano dodatki Service Pack

Niestety nie działa, ponieważ wersja mscorlib.dll w katalogu 2.0 ma wersję 2.0 i nie ma wersji mscorlib.dll w katalogach 3.0 lub 3.5, mimo że 3.5 SP1 jest zainstalowany ... dlaczego czy oficjalna odpowiedź Microsoft byłaby tak źle poinformowana?

zaraz
źródło
2
+1 - Wygląda na to, że Microsoft mógł zaktualizować tę stronę, ponieważ pierwotnie był z nią połączony. Wygląda na to, że może to być jedno z najlepszych oficjalnych źródeł w tej sprawie.
jpierson
2
To idzie tylko do 4.0
użytkownik316117
16

Framework 4 beta instaluje się na innym kluczu rejestru.

using System;
using System.Collections.ObjectModel;
using Microsoft.Win32;

class Program
{
    static void Main(string[] args)
    {
        foreach(Version ver in InstalledDotNetVersions())
            Console.WriteLine(ver);

        Console.ReadKey();
    }


    public static Collection<Version> InstalledDotNetVersions()
    {
        Collection<Version> versions = new Collection<Version>();
        RegistryKey NDPKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP");
        if (NDPKey != null)
        {
            string[] subkeys = NDPKey.GetSubKeyNames();
            foreach (string subkey in subkeys)
            {
                GetDotNetVersion(NDPKey.OpenSubKey(subkey), subkey, versions);
                GetDotNetVersion(NDPKey.OpenSubKey(subkey).OpenSubKey("Client"), subkey, versions);
                GetDotNetVersion(NDPKey.OpenSubKey(subkey).OpenSubKey("Full"), subkey, versions);
            }
        }
        return versions;
    }

    private static void GetDotNetVersion(RegistryKey parentKey, string subVersionName, Collection<Version> versions)
    {
        if (parentKey != null)
        {
            string installed = Convert.ToString(parentKey.GetValue("Install"));
            if (installed == "1")
            {
                string version = Convert.ToString(parentKey.GetValue("Version"));
                if (string.IsNullOrEmpty(version))
                {
                    if (subVersionName.StartsWith("v"))
                        version = subVersionName.Substring(1);
                    else
                        version = subVersionName;
                }

                Version ver = new Version(version);

                if (!versions.Contains(ver))
                    versions.Add(ver);
            }
        }
    }
}
środek przestrzeni
źródło
1
Zmień, Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP", true)aby Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP")uniknąć wyjątku bezpieczeństwa dla użytkowników niebędących administratorami.
Jon Cage
Fajnie, użyłem LinqPada i to dało mi doskonałe wyniki! share.linqpad.net/5cjihh.linq
user917170
Dziwne jest dzielenie się małymi szczegółami (np. Która wersja dodatku Service Pack jest zainstalowana), ale ważniejsze informacje (jeśli framework jest zainstalowany tylko częściowo lub całkowicie) są ignorowane przez Twój kod !! Błędem jest traktować klucze rejestru „Klient” i „Pełny” tak, jakby były takie same. Jeśli wyjdzie tylko klucz „Klient”, na przykład System.Web nie będzie dostępny. Te ważne informacje powinny zostać również zwrócone przez Twój kod! Jeśli użytkownik odinstalował „.NET Framework 4 Extended” w Panelu sterowania, będzie brakowało kilku zestawów.
Elmue,
8

Chciałem wykryć obecność .NET w wersji 4.5.2 zainstalowanej w moim systemie i nie znalazłem lepszego rozwiązania niż ASoft .NET Version Detector .

Migawka tego narzędzia pokazująca różne wersje .NET:

Migawka tego narzędzia pokazująca różne wersje .NET

Faisal Mq
źródło
7

Wymień podklucze HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP. Każdy podklucz jest wersją .NET . Powinien mieć Install=1wartość, jeśli jest obecna na komputerze, wartość SP pokazującą dodatek Service Pack i MSI=1wartość, jeśli została zainstalowana przy użyciu MSI. (.NET 2.0 w systemie Windows Vista nie ma na przykład ostatniego, ponieważ jest częścią systemu operacyjnego).

Franci Penov
źródło
Nie znalazłem tego klucza na moim komputerze (XP Pro), ale miałem go: HKLM \ SOFTWARE \ Microsoft \ .NETFramework. Jednak różne wartości, które opisujesz, nie istnieją dla mnie.
Charlie
Powinieneś mieć ten klucz, jeśli masz .NET 1.1 lub nowszy zainstalowany. Wspomniany klucz był używany tylko w .NET 1.0.
Scott Dorman
reg zapytanie „HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ NET Framework Setup \ NDP”
entuzjastyczny
5

W 64-bitowym systemie operacyjnym ścieżka wyglądałaby następująco:

HKEY_LOCAL_MACHINE\SOFTWARE\wow6432Node\Microsoft\NET Framework Setup\NDP\
abhishek mehta
źródło
10
To tylko „nieco” prawda. Rejestr w 64-bitowych wersjach systemu Windows jest podzielony na klucze 32-bitowe i 64-bitowe (wiele kluczy 32-bitowych ma taką samą nazwę jak klucze 64-bitowe). Wow6432NodeKlucz rejestru jest częścią odbłyśnika rejestru WOW64, który lusterka pewne klucze i wartości między 64-bitowych i 32-bitowych widokiem rejestru. Bezpośredni dostęp do tego klucza nie powinien być konieczny, ponieważ rejestr automatycznie obsługuje przekierowanie i dublowanie.
Scott Dorman,
5

Aktualizacja dla .NET 4.5.1

Teraz, gdy .NET 4.5.1 jest dostępny, należy sprawdzić rzeczywistą wartość klucza o nazwie Release w rejestrze, a nie tylko jego istnienie. Wartość 378758 oznacza, że ​​.NET Framework 4.5.1 jest zainstalowany. Jednak, jak opisano tutaj, ta wartość to 378675 w systemie Windows 8.1.

JasonMcF
źródło
5

Dostępne jest narzędzie GUI, ASoft .NET Version Detector , który zawsze był wysoce niezawodny. Może tworzyć pliki XML, podając w wierszu poleceń nazwę pliku wyjściowego XML.

Możesz użyć tego do automatyzacji. Jest to mały program napisany w języku innym niż .NET i nie wymaga instalacji.

CarlR
źródło
4

Musiałem dowiedzieć się, którą wersję środowiska .NET miałem na swoim komputerze, i wystarczyłem przejść do panelu sterowania i wybrać opcję „Odinstaluj program”. Następnie posortowałem programy według nazwy i znalazłem profil klienta Microsoft .NET Framework 4.

Kudzai K
źródło
1
Dzięki - Każde inne „rozwiązanie”, które wypróbowałem, było wadliwe i nie działało. Tak się stało.
user20493
Powodem, dla którego szukałem tych informacji, było to, że elementy w Odinstaluj program są całkowicie zawodne, przynajmniej jeśli chodzi o .NET Framework.
tobbenb3
3

Oto skrypt PowerShell w celu uzyskania zainstalowanych wersji środowiska .NET

function Get-KeyPropertyValue($key, $property)
{
    if($key.Property -contains $property)
    {
        Get-ItemProperty $key.PSPath -name $property | select -expand $property
    }
}

function Get-VersionName($key)
{
   $name = Get-KeyPropertyValue $key Version
   $sp = Get-KeyPropertyValue $key SP
   $install = Get-KeyPropertyValue $key Install
   if($sp)
   {
        "$($_.PSChildName) $name SP $sp"
   }
   else{
    "$($_.PSChildName) $name"
   }
}

function Get-FrameworkVersion{
   dir "hklm:\SOFTWARE\Microsoft\NET Framework Setup\NDP\" |? {$_.PSChildName -like "v*"} |%{
    if( $_.Property -contains "Version")
    {
        Get-VersionName $_
    }
    else{
        $parent = $_
        Get-ChildItem $_.PSPath |%{
            $versionName = Get-VersionName $_
            "$($parent.PSChildName) $versionName"
            }
        }
    }
}


$v4Directory = "hklm:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"
if(Test-Path $v4Directory)
{
    $v4 = Get-Item $v4Directory
    $version = Get-KeyPropertyValue $v4 Release
    switch($version){
        378389 {".NET Framework 4.5"; break;}
        378675 {".NET Framework 4.5.1 installed with Windows 8.1 or Windows Server 2012 R2"; break;}
        378758 {".NET Framework 4.5.1 installed on Windows 8, Windows 7 SP1, or Windows Vista SP2"; break;}
        379893 {".NET Framework 4.5.2"; break;}
        { 393295, 393297 -contains $_} {".NET Framework 4.6"; break;}
        { 394254, 394271 -contains $_} {".NET Framework 4.6.1"; break;}
        { 394802, 394806 -contains $_} {".NET Framework 4.6.2"; break; }
    }
}

Został napisany w oparciu o: Jak ustalić, które wersje .NET Framework są zainstalowane . Użyj funkcji THE Get-FrameworkVersion (), aby uzyskać informacje o zainstalowanych wersjach środowiska .NET.

cezarypiatek
źródło
2

Korzystając z biblioteki Signum.Utilities z SignumFramework (z której można korzystać autonomicznie), można uzyskać ją ładnie i bez samodzielnego zajmowania się rejestrem:

AboutTools.FrameworkVersions().ToConsole();
//Writes in my machine:
//v2.0.50727 SP2
//v3.0 SP2
//v3.5 SP1
mapache
źródło
2
Patrząc na kod tej metody, nie jest ona bardzo kompletna, jeśli chodzi o używane klucze rejestru i całkowicie pominie .NET 1.0 i nie rozróżnia .NET 2.0 (RTM) od .NET 2.0 SP1. Nie bierze również pod uwagę zależności między wersjami frameworka.
Scott Dorman,
2
Niezbyt dobre rozwiązanie. Nie ma żadnego powodu, aby pobierać całą bibliotekę tylko po to, aby uzyskać wersję .NET, gdy możesz wykonać tę samą pracę w około 3 liniach kodu. Jako programista MUSISZ być w stanie „samodzielnie poradzić sobie z rejestrem”.
TheSmurf
3
@DannySmurf Nie zgadzam się. Kiedy .NET 3.0 został wprowadzony, MS powinien był zapakować to w .NET API (jak tylko mieliśmy więcej niż jedną warstwę FX na tym samym CLR). Wolałbym, żeby moja aplikacja korzystała z biblioteki narzędzi, a kiedy pojawią się 4.1, 6.1, 7.100, mogę po prostu zaktualizować bibliotekę i pozycję konfiguracji, dla której warstwy .NET wymaga moja aplikacja. Oczywiście ten argument nie trzyma wody, jeśli żadna z bibliotek nie działa.
yzorg
1

Zobacz : Określanie, które wersje .NET Framework są zainstalowane (MSDN).

MSDN proponuje jeden przykład funkcji, która wydaje się wykonywać zadanie dla wersji 1-4. Zgodnie z artykułem dane wyjściowe metody to:

v2.0.50727  2.0.50727.4016  SP2
v3.0  3.0.30729.4037  SP2
v3.5  3.5.30729.01  SP1
v4
  Client  4.0.30319
  Full  4.0.30319

Zauważ, że dla „wersji 4.5 i nowszych” istnieje inna funkcja.

Olivier de Rivoyre
źródło
1

W systemie Windows 7 (powinien działać również w systemie Windows 8, ale go nie testowałem):

Przejdź do wiersza polecenia

Kroki, aby przejść do wiersza polecenia:

  1. Kliknij menu Start
  2. W polu wyszukiwania wpisz „cmd” (bez cudzysłowów)
  3. Otwórz cmd.exe

W cmd wpisz to polecenie

wmic /namespace:\\root\cimv2 path win32_product where "name like '%%.NET%%'" get version

To daje najnowszą zainstalowaną wersję NET Framework.

Można również wypróbować narzędzia Raymond.cc Utilties .

Mayank Agarwal
źródło
1
Uruchomienie tej linii cmddaje mi ERROR: Description = Invalid namespace.
UWAGI
dostaję takżeERROR: Description = Invalid namespace
Peter
To polecenie powoduje błąd! (wykonywany z terminala Windows 7)
Smrita,
Dziękuję MEMark, Peter, Smrita za powiadomienie.
Mayank Agarwal