gpt4 book ai didi

c# - 面向 future 的 .NET 版本检测

转载 作者:行者123 更新时间:2023-11-30 13:41:47 26 4
gpt4 key购买 nike

不要击败dead horse但是,我正在寻找一种方法来检测已安装的 .NET 框架。似乎提供的解决方案(在链接中)都很好,直到发布了新版本的框架,然后所有的赌注都被取消了。原因是检测依赖于注册表项,框架的 v4 似乎打破了惯例,现在必须采取额外的步骤来检测 v4。

有没有一种方法可以检测在 .NET v5 出现时也能正常工作的 .NET 框架。

编辑:好的,对于后代沮丧的 .NET 版本寻求者,这里是实现它的代码:

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

private List<string> GetInstalledDotNetFrameworks()
{
string key = string.Empty;
string version = string.Empty;
List<string> frameworks = new List<string>();

var matches = Registry.LocalMachine
.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP")
.GetSubKeyNames().Where(keyname => Regex.IsMatch(keyname, @"^v\d"));


// special handling for v4.0 (deprecated) and v4 (has subkeys with info)
foreach (var item in matches)
{
switch (item)
{
case "v4.0": // deprecated - ignore
break;

case "v4":// get more info from subkeys

key = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\" + item;
string[] subkeys = Registry.LocalMachine
.OpenSubKey(key)
.GetSubKeyNames();


foreach (var subkey in subkeys)
{
key = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\" + item + @"\" + subkey;
version = Registry.LocalMachine
.OpenSubKey(key)
.GetValue("Version").ToString();

version = string.Format("{0} ({1})", version, subkey);
frameworks.Add(version);
}


break;
case "v1.1.4322": // special case, as the framework does not follow convention
frameworks.Add(item);
break;
default:

try
{
// get the Version value
key = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\" + item;
version = Registry.LocalMachine
.OpenSubKey(key)
.GetValue("Version").ToString();

frameworks.Add(version);

}
catch
{
// most likely new .NET Framework got introduced and broke the convention
}

break;

}

}

// sort the list, just in case the registry was not sorted
frameworks.Sort();

return frameworks;
}

最佳答案

简而言之,你可以大致使用这个(更完整的解决方案见下文):

Microsoft.Win32.Registry.LocalMachine
.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP")
.GetSubKeyNames().Where(keyname=>Regex.IsMatch(keyname,@"^v\d"))

在我的机器上,返回:v2.0.50727、v3.0、v3.5、v4、v4.0。子项可用于检测服务包(可能相关)。此外,使用 key SOFTWARE\Microsoft\.NETFramework 返回 v2.0.50727、v3.0 和 v4.0.30319 - 嗯,可爱,略有不同!

不能保证这种模式会成立,但这是一个相当合理的赌注:-)。 http://support.microsoft.com/kb/318785有一些关于描述版本控制的注册表细节的更多信息,特别是,您可能需要检查Install - 但正如 v4.0 所示,这很棘手。

编辑: 我对此进行了扩展以检测包含安装信息的注册表的任意子项,以便正确检测 v4 客户端和完整配置文件。此外,RegistryKey 类型是 IDisposable,看起来 Dispose 方法确实在做某事(注册表键解锁)。

var versionList = new List<string>();
using(var ndpKey=Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP")) {
Action<RegistryKey, Action<RegistryKey,string>> processKids = (node, action) => {
foreach(var childname in node.GetSubKeyNames())
using(var child = node.OpenSubKey(childname))
action(child,childname);
};

Action<RegistryKey, Func<RegistryKey, bool>> visitDescendants = null;
visitDescendants = (regkey, isDone) => {
if(!isDone(regkey))
processKids(regkey, (subkey, subkeyname)=>visitDescendants(subkey,isDone));
};

processKids(ndpKey, (versionKey, versionKeyName) => {
if(Regex.IsMatch(versionKeyName,@"^v\d")) {
visitDescendants(versionKey, key => {
bool isInstallationNode = Equals(key.GetValue("Install"), 1) && key.GetValue("Version") != null;
if(isInstallationNode)
versionList.Add(
key.Name.Substring(ndpKey.Name.Length+1)
+ (key.GetValue("SP")!=null ? ", service pack "+ key.GetValue("SP"):"")
+ " ("+key.GetValue("Version") +") "
);
return isInstallationNode;
});
}
});
}

versionList 然后包含:

v2.0.50727, service pack 2 (2.0.50727.4927)   
v3.0, service pack 2 (3.0.30729.4926)
v3.5, service pack 1 (3.5.30729.4926)
v4\Client (4.0.30319)
v4\Full (4.0.30319)

关于c# - 面向 future 的 .NET 版本检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4558283/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com