C#和非托管本机C ++是否有通用的方法来确定已安装的CLR版本?

时间:2012-03-18 12:46:08

标签: c# c++ .net clr clr-hosting

正如标题所说:C#中是否存在常用方式,尤其是非托管本机C ++以确定已安装的CLR版本?这意味着不仅要检查是否根据this KB article安装了Framework。我想通过使用CLR接口来完成它,对于CLR1,CLR1.1和CLR2已完成here。通过这种方式,我可以确保它们真正安装。但这不适用于CLR4。任何想法?

我的目标是创建一个可用的CLR版本的枚举,如Clrver(无论进程列表功能是否正确)。

2 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:-1)

在阅读Jeffrey Richters的书Applied Microsoft® .NET Framework Programming时,我发现了一些有趣的提示。面向主题加载公共语言运行时(p.41),他提到检查注册表路径(和子项)HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\policy以检查已安装的运行时。因此,我发现了一个有趣KB article的主题。此外,在运行时如何解析类型引用(p.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当Clrver列出它时,列表installedRuntimes内的版本字符串。