然而,为了不击败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;
}发布于 2010-12-30 07:12:44
简而言之,您可以大致使用它(更完整的解决方案见下文):
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。子键可用于检测服务包(可能是相关的)。此外,使用密钥SOFTWARE\Microsoft\.NETFramework返回v2.0.50727、v3.0和v4.0.30319 - ehhh,可爱,略有不同!
不能保证这种模式会保持下去,但这是一个相当合理的赌注:-)。http://support.microsoft.com/kb/318785有更多关于描述版本控制的注册表细节的信息,特别是,您可能需要检查Install -但正如v4.0演示的那样,这是棘手的。
编辑:我已经将其扩展到检测注册表中包含安装信息的任意子项,以便正确检测v4客户端和完整配置文件。另外,Dispose类型是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) 发布于 2010-12-30 06:13:27
你希望我们能告诉你未来吗?:)你为什么首先需要它?我的意思是,如果你为v4写了一个应用程序,安装了v5还是没有安装有什么区别呢?你可以在app.config中指定你支持的版本,但你不能提前知道下一个版本是什么,甚至不知道你的应用程序是否会在上面运行。每当一个新的框架出现时,你就必须测试你的应用程序,并决定是否要迁移。如果您进行迁移,则需要对app.config和代码进行更改,并发布一个新版本。如果不这样做,那么您仍然需要安装一个较旧的框架版本。这并不是说v5出现了,人们就会开始卸载所有以前的框架。我的机器上仍然有v1.1和v2,我猜它们会停留一段时间。
发布于 2010-12-30 06:18:17
我同意fejesjoco的观点。为什么你甚至想要检测一个你的代码还没有编译过的未来版本呢?
如果您查看框架文件夹(C:\Windows\Microsoft.NET\Framework),您将看到所有以前版本的框架都与最新版本一起安装。如果您的代码是针对4.0编译的,并且5.0发布了,那么它仍然会有一个用于4.0的文件夹。
如果你能给我们提供更多的上下文,为什么你想要检测未来的版本,我们可能会更好地帮助你。
https://stackoverflow.com/questions/4558283
复制相似问题