3

正如标题所说:在 C# 中,尤其是非托管原生 C++ 中是否有一种通用的方法来确定已安装的 CLR 版本?这意味着不只是根据这篇知识库文章检查是否安装了框架。我想通过使用 CLR 接口来做到这一点,就像这里对 CLR1、CLR1.1 和 CLR2 所做的那样。通过这种方式,我可以确保它们确实已安装。但这不适用于 CLR4。有任何想法吗?

我的目标是创建一个可用的 CLR 版本的枚举,例如Clrver(不管进程列表功能)。

4

2 回答 2

5

“通用方式”与否,但Codeplex 的 dotNetInstaller 在本机、非托管 C++ 代码中执行此操作。
因为它是开源的,所以看看他们是如何做到的。

此外,您可以使用ICLRMetaHost::EnumerateInstalledRuntimes 方法来检测 .NET v4+ 和GetRequestedRuntimeInfoInfo(与clrver.cpp的做法非常相似)来检测 .NET v1 - v2。所以你必须打两个电话,但这应该涵盖它。

于 2012-03-18T13:28:13.717 回答
-1

在阅读 Jeffrey Richters 的《Applied Microsoft® .NE​​T Framework Programming 》一书时,我发现了一些关于该主题的有趣提示。关于加载公共语言运行时(第 41 页)的主题,他提到检查注册表路径(和子项)HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\policy以检查已安装的运行时。因此,我发现了一篇关于该主题的有趣的知识库文章。此外,在运行时如何解析类型引用(第 132 页)一节中,他提到mscorlib.dll与 CLR 版本相关联。所以我认为应该可以根据这个文件及其版本检查找到的注册表项,以确保找到的密钥是安装的 CLR 版本。

在下文中,您将在代码中找到我对此的结论。:) 我认为 Clrver 做了类似的事情。而且我认为这个解决方案也应该适用于本机 C++ 应用程序,因为我的以下代码是 C# 并且只是使用非常基本的框架函数。

List<string> installedRuntimes = new List<string>();

Regex rxVersion = new Regex(@"^[v](\d{1,5})([\.](\d{1,5})){0,3}$");
Regex rxVersionPart = new Regex(@"^\d{1,5}$");            

try
{
    string installPath = Convert.ToString(Registry.GetKey("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/.NETFramework").GetValue("InstallRoot"));
    string[] shortVersions = Registry.GetKey("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/.NETFramework/Policy", false).GetSubKeyNames();
    foreach (string shortVersion in shortVersions)
        if (rxVersion.IsMatch(shortVersion))
        {
            string[] versionExtensions = Registry.GetKey("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/.NETFramework/Policy/" + shortVersion, false).GetValueNames();
            foreach (string versionExtension in versionExtensions)
                if (rxVersionPart.IsMatch(versionExtension))
                {
                    string fullVersion = shortVersion + "." + versionExtension;
                    if (rxVersion.IsMatch(fullVersion))
                    {
                        string clrPath = installPath + fullVersion + "\\mscorlib.dll";
                        if (File.Exists(clrPath) && FileVersionInfo.GetVersionInfo(clrPath).FileVersion.StartsWith(fullVersion.Substring(1))) installedRuntimes.Add(fullVersion);
                    }
                }
        }
}
catch { } // May fails while getting a specific registry key, if Microsoft changes the naming rules.

(不要搞砸了Registry.GetKey(...)- 它只是 .NET 注册表功能的包装器,以简化我习惯使用注册表的方式。)最后,您应该在列表中包含 CLR 版本字符串installedRuntimes作为 Clrver 列表它。

于 2012-04-09T22:46:41.663 回答