Is there a general way for C # and unmanaged native C ++ to determine installed CLR versions?

As the title says: Is there a general way in C # and especially unmanaged native C ++ to determine installed CLR versions? This means more than just checking to see if the Framework is installed according to this KB article . I want to do this using the CLR interface as done here for CLR1, CLR1.1, and CLR2. This way I can make sure that they are actually installed. But this is not the case for CLR4. Any ideas?

My goal is to create an enumeration of the available CLR versions like Clrver (regardless of the process list functionality).

+3


source to share


2 answers


"The usual way" or not, dotNetInstaller at Codeplex does it in native unmanaged C ++ code.
SInce its open source, see how they do it.



Alternatively, you can use ICLRMetaHost :: EnumerateInstalledRuntimes Method to detect .NET v4 + and GetRequestedRuntimeInfoInfo (much the same as clrver.cpp ) to detect .NET v1 - v2. So you need to make two calls, but that should cover it.

+5


source


While reading Jeffrey Richter's book Applied Programming of the Microsoft .NET Framework I found some interesting hints on this topic. To the topic Downloading the Common Language Runtime version (p. 41) he mentioned to check the registry path (and subkeys) HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\policy

to check the set duration. So I found an interesting KB article regarding this topic. Also, in the section "How Runtime Resolves Type References" (page 132), he mentioned that mscorlib.dll is tied to the CLR version. Therefore, I think that you need to check the found registry keys for this file and its version to make sure that the found key is installed in the CLR version.

In the next one you will find my conclusion about this in the code. :) I think that Clrver does something similar. And I think this solution should be applicable for a native C ++ application as well, since my next code is C # and just uses very simple framework functions.



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.

      

(Not to be confused with Registry.GetKey(...)

- this is just a wrapper for the .NET Registry feature to make it easier in regards to how I'm used to using the registry.) At the end, you should have the CLR version lines inside the list installedRuntimes

, as Clrver lists it.

-1


source







All Articles