问题是我需要知道它是否是版本3.5 SP 1. Environment.Version()只返回2.0.50727.3053.
我找到了这个解决方案,但我认为这需要花费更多的时间而不是它的价值,所以我正在寻找一个更简单的解决方案.可能吗?
Fac*_*tic 95
这样的事情应该做到这一点.只需从注册表中获取值即可
对于.NET 1-4:
Framework是安装的最高版本,SP是该版本的Service Pack.
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));
Run Code Online (Sandbox Code Playgroud)
对于.NET 4.5+(来自官方文档):
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";
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*zen 21
不知道为什么没有人建议遵循从微软官方建议的权利在这里.
这是他们推荐的代码.当然它很丑,但它确实有效.
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);
}
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
// 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.");
}
}
}
Run Code Online (Sandbox Code Playgroud)
mwi*_*nds 12
另一种无需访问注册表权限的方法是检查特定框架更新中引入的类是否存在.
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;
}
Run Code Online (Sandbox Code Playgroud)
qui*_*ker 10
Environment.Version()正在给出一个不同问题的正确答案.在.NET 2.0,3和3.5中使用相同版本的CLR.我想您可以检查GAC以查找在每个后续版本中添加的库.
它过去很容易,但微软决定做出重大改变:在 4.5版之前,每个版本的.NET都位于下面的C:\Windows\Microsoft.NET\Framework子目录(子目录v1.0.3705, v1.1.4322, v2.0.50727, v3.0, v3.5和v4.0.30319)中.
从版本4.5开始,这已经改变了:每个版本的.NET(即4.5.x,4.6.x,4.7.x)都安装在同一个子目录中v4.0.30319- 因此您不再能够通过查看来检查已安装的.NET版本进入Microsoft.NET\Framework.
为了检查.NET版本,Microsoft根据正在检查的.NET版本提供了两个不同的示例脚本,但我不喜欢有两个不同的C#脚本.所以我尝试将它们合并为一个,这是我创建的脚本(并为4.7.1框架更新它):
using System;
using Microsoft.Win32;
public class GetDotNetVersion
{
public static void Main()
{
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
Run Code Online (Sandbox Code Playgroud)
在我的机器上输出:
v2.0.50727 2.0.50727.4927 SP2
v3.0 3.0.30729.4926 SP2
v3.5 3.5.30729.4926 SP1
v4
客户端4.7.02558
完整4.7.02558
v4.0
客户端4.0.0.0
.NET Framework版本:4.7.1或更高版本
****找到的最大.NET版本号是:4.7.1或更高版本****
随着时间的推移,唯一需要维护的是.NET版本大于4.7.1时的内部版本号 - 可以通过修改功能轻松完成CheckFor45PlusVersion,您需要知道新版本的发布密钥然后你可以添加它.例如:
if (releaseKey >= 461308) return "4.7.1 or later";
Run Code Online (Sandbox Code Playgroud)
此版本密钥仍然是最新版本,对Windows 10的Fall Creators更新有效.如果您仍在运行其他(较旧的)Windows版本,则根据Microsoft的此文档还有另一个版本:
.NET Framework 4.7.1安装在所有其他Windows操作系统版本461310上
所以,如果你也需要,你必须添加
if (releaseKey >= 461310) return "4.7.1 or later";
Run Code Online (Sandbox Code Playgroud)
到函数的顶部CheckFor45PlusVersion.
注意:您不需要安装Visual Studio,甚至不需要PowerShell - 您可以使用它csc.exe来编译和运行上面的脚本,我在这里已经介绍过了.
更新:问题是关于.NET Framework,为了完整起见,我想提一下如何查询.NET Core的版本 - 与上面相比,这很容易:打开一个命令shell并输入:dotnet --info Enter它还将列出.NET Core版本号,Windows版本以及每个相关运行时DLL的版本.样本输出:
.NET Core SDK(反映任何global.json):
版本:2.1.300
提交:adab45bf0c
运行时环境:
操作系统名称:Windows
操作系统版本:10.0.15063
操作系统平台:Windows
RID:win10-x64
基本路径:C:\ Program Files\dotnet\sdk\2.1.300 \
Host(对支持很有用):
版本:2.1.0
提交:caa7b7e2ba
.NET Core SDK安装:
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核心运行时:
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]
要安装其他.NET Core运行时或SDK:
https:// aka. MS/DOTNET下载
我遇到过我的 .NET 4.0 类库可能从 .NET 4.0 或更高版本的程序集调用的情况。
特定的方法调用仅在从 4.5+ 程序集执行时才有效。
为了决定我是否应该调用该方法,我需要确定当前正在执行的框架版本,这是一个很好的解决方案
var frameworkName = new System.Runtime.Versioning.FrameworkName(
AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName
);
if (frameworkName.Version >= new Version(4, 5))
{
// run code
}
Run Code Online (Sandbox Code Playgroud)
这适用于 4.0 程序集
var featureEnabled = GetCurrentFrameworkName().Version >= new Version(4, 5);
public static FrameworkName GetCurrentFrameworkName()
{
// AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName
// is missing prior to .NET 4.5
var targetFrameworkName = (string)AppDomain
.CurrentDomain
.SetupInformation
.GetType()
.GetProperty("TargetFrameworkName")?
.GetValue(AppDomain.CurrentDomain.SetupInformation, null) ?? ".NETFramework,Version=v4.0.0";
return new FrameworkName(targetFrameworkName);
}
Run Code Online (Sandbox Code Playgroud)
此类允许您的应用程序在找不到正确的 .NET 版本时抛出优雅的通知消息,而不是崩溃和烧毁。您需要做的就是在主代码中执行以下操作:
[STAThread]
static void Main(string[] args)
{
if (!DotNetUtils.IsCompatible())
return;
. . .
}
Run Code Online (Sandbox Code Playgroud)
默认情况下它需要 4.5.2,但您可以根据自己的喜好调整它,类(随意用控制台替换 MessageBox):
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;
}
}
Run Code Online (Sandbox Code Playgroud)
当他们稍后添加新版本时可轻松扩展。在 4.5 之前我没有打扰任何事情,但你明白了。
我试图将所有答案合并成一个整体。
使用:
NetFrameworkUtilities.GetVersion()此时将返回当前可用的.NET Framework版本,如果不存在则返回null 。
此示例适用于 .NET Framework 版本 3.5+。它不需要管理员权限。
我想指出的是,您可以使用运算符 < 和 > 检查版本,如下所示:
var version = NetFrameworkUtilities.GetVersion();
if (version != null && version < new Version(4, 5))
{
MessageBox.Show("Your .NET Framework version is less than 4.5");
}
Run Code Online (Sandbox Code Playgroud)
代码:
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 >= 528040) return new Version(4, 8, 0);
if (releaseKey >= 461808) return new Version(4, 7, 2);
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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)