In passato era facile, ma Microsoft ha deciso di apportare una modifica sostanziale: prima della versione 4.5, ogni versione di .NET risiedeva nella propria directory sottostante C:\Windows\Microsoft.NET\Framework(sottodirectory v1.0.3705, v1.1.4322, v2.0.50727, v3.0, v3.5e v4.0.30319).
Dalla versione 4.5 questo è stato cambiato: ogni versione di .NET (cioè 4.5.x, 4.6.x, 4.7.x, 4.8.x, ...) viene installata nella stessa sottodirectory v4.0.30319, quindi non sei più in grado di farlo controlla la versione .NET installata esaminando Microsoft.NET\Framework.
Per controllare la versione .NET, Microsoft ha fornito due diversi script di esempio a seconda della versione .NET che viene controllata, ma non mi piace avere due diversi script C # per questo. Quindi ho provato a combinarli in uno, ecco lo script che GetDotNetVersion.csho creato (e aggiornato per il framework 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;
}
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";
return "No 4.5 or later version detected";
}
private static string GetVersionFromRegistry()
{
String maxDotNetVersion = "";
using (RegistryKey ndpKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "")
.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 == "")
{
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 == "")
{
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;
}
}
}
}
}
}
return maxDotNetVersion;
}
}
Sulla mia macchina emette:
v2.0.50727 2.0.50727.4927 SP2
v3.0 3.0.30729.4926 SP2
v3.5 3.5.30729.4926 SP1
v4
Client 4.7.03056
Full 4.7.03056
v4.0
Client 4.0.0.0
Versione .NET Framework: 4.7.2 o successiva
*** * Il numero massimo di versioni .NET trovato è: 4.7.2 o successivo ****
L'unica cosa che deve essere mantenuta nel tempo è il numero di build una volta che esce una versione .NET maggiore di 4.7.1 - ciò può essere fatto facilmente modificando la funzione CheckFor45PlusVersion, è necessario conoscere la chiave di rilascio per la nuova versione quindi tu puoi aggiungerlo. Per esempio:
if (releaseKey >= 461308) return "4.7.1 or later";
Questa chiave di rilascio è ancora l'ultima ed è valida per l'aggiornamento Fall Creators di Windows 10. Se stai ancora utilizzando altre versioni (precedenti) di Windows, ce n'è un'altra come da questa documentazione di Microsoft:
.NET Framework 4.7.1 installato su tutte le altre versioni del sistema operativo Windows 461310
Quindi, se hai bisogno anche di quello, dovrai aggiungere
if (releaseKey >= 461310) return "4.7.1 or later";
all'inizio della funzione CheckFor45PlusVersion. Allo stesso modo funziona per le versioni più recenti. Ad esempio, recentemente ho aggiunto l'assegno per 4.8. Di solito puoi trovare quei numeri di build su Microsoft.
Nota: non è necessario installare Visual Studio, nemmeno PowerShell: è possibile utilizzare csc.exeper compilare ed eseguire lo script sopra, che ho descritto qui.
Aggiornamento: la domanda riguarda .NET Framework, per completezza vorrei menzionare come interrogare anche la versione di .NET Core - rispetto a quanto sopra, è facile: apri una shell dei comandi e digita:
dotnet --info Enter
e elencherà anche il numero di versione di .NET Core, la versione di Windows e le versioni di ciascuna DLL di runtime correlata. Output di esempio:
.NET Core SDK (che riflette qualsiasi global.json):
Versione: 2.1.300
Commit: adab45bf0c
Ambiente di runtime:
Nome sistema
operativo : Windows Versione sistema
operativo: 10.0.15063
Piattaforma sistema operativo: Windows
RID: win10-x64
Percorso di base: C: \ Programmi \ dotnet \ sdk \ 2.1.300
Host (utile per il supporto):
Versione: 2.1.0
Commit: caa7b7e2ba
.NET Core SDK installati:
1.1.9 [C: \ Program Files \ dotnet \ sdk]
2.1.102 [C: \ Program Files \ dotnet \ sdk]
...
2.1.300 [C: \ Program Files \ dotnet \ sdk] Runtime
.NET Core installati:
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]
Per installare ulteriori runtime .NET Core o SDK:
https://aka.ms/dotnet-download
Nota quello
se hai bisogno solo del numero di versione senza tutte le informazioni aggiuntive, puoi usare
dotnet --version.
su un PC Windows a 64 bit è possibile installare la versione x86 affiancata alla versione x64 di .NET Core. In questo caso, otterrai solo la versione che viene prima nella variabile d'ambiente PATH. Ciò è particolarmente importante se devi tenerlo aggiornato e vuoi conoscere ogni versione. Per interrogare entrambe le versioni, usa:
C: \ Programmi \ dotnet \ dotnet.exe --version
3.0.100-preview6-012264
C: \ Programmi (x86) \ dotnet \ dotnet.exe --version
3.0.100-preview6-012264
Nell'esempio sopra, entrambi sono uguali, ma se hai dimenticato di aggiornare entrambe le istanze, potresti ottenere risultati diversi! Nota che Program Filesè per la versione a 64 bit ed Program Files (x86)è la versione a 32 bit .
Aggiornamento: se preferisci mantenere i numeri di build in un elenco piuttosto che in una cascata di istruzioni if (come suggerito da Microsoft), puoi utilizzare questo codice per CheckFor45PlusVersion:
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";
}
Environment.Version()probabilmente restituisce solo la versione del CLR.