Unable to query value of CSDVersion
<p>I followed this C# example and am able to query some registry values, but not all of them:</p>

<p><a href="http://stackoverflow.com/questions/1155633/how-to-obtain-a-registry-value-from-a-remote-machine-if-i-dont-know-its-type">How to obtain a registry value from a remote machine if I don&#39;t know its type? (C#)</a></p>

<p>I can reliably get registry keys such as the CurrentVersion, the ProductName, etc. But when I try to get the CSDVersion, it's failing.</p>

<p>I've compiled in both .NET 2.0 and .NET 4.0, but with the same results. I've tried querying the local machine and a remote machine. Both are able to return other registry values, but not this particular one.</p>

<p>Both are x64 machines (Windows 7 Ultimate and Windows 2008 R2) so neither should have any problems with getting to the registry either way.</p>

<p>One weird thing I've found is that the EnumValues function only returns 17 values, and there are 21 in this particular registry key. Of the four that are missing, CSDVersion is one of them.</p>

<p>I'm curious if anyone knows why these four values wouldn't come back, but all of the rest would?
Missing Values:</p>

<ul>
<li>CSDVersion - Reg_sz</li>
<li>DigitalProductID - Reg_binary</li>
<li>DigitalProductId4 - Reg_binary</li>
<li>ProductID - Reg_sz</li>
</ul>

<p>Something that's really bizarre is that I have another project which was written in .NET 2.0 and has a class library that does this kind of thing. When running the NUnit tests for the library, this query works fine and returns all 21 values. But when running this library through another project, it doesn't work.</p>

<p>I've stepped through the code in the project that calls the library and when doing that, it only returns 17 entries. So I'm at a loss to explain what's going on.</p>

<p>Anyone have any ideas of where to go next? Below is the exact code I'm using and it simply doesn't work for the above specific cases</p>

<pre><code>using System;
using System.Management;
using System.Management.Instrumentation;

namespace GetCSDVersion
{
    public enum RegHive : uint
    {
        HKEY_CLASSES_ROOT = 0x80000000,
        HKEY_CURRENT_USER = 0x80000001,
        HKEY_LOCAL_MACHINE = 0x80000002,
        HKEY_USERS = 0x80000003,
        HKEY_CURRENT_CONFIG = 0x80000005
    }

    public enum RegType
    {
        REG_SZ = 1,
        REG_EXPAND_SZ,
        REG_BINARY,
        REG_DWORD,
        REG_MULTI_SZ = 7
    }

    class Program
    {
        static void Main(string[] args)
        {
            const string strComputer = "localhost";

            ConnectionOptions options = new ConnectionOptions();
            options.Impersonation = ImpersonationLevel.Impersonate;
            options.EnablePrivileges = true;
            //options.Username = "";
            //options.Password = "";

            ManagementScope myScope = new ManagementScope("\\\\" + strComputer + "\\root\\default", options);
            ManagementPath mypath = new ManagementPath("StdRegProv");
            ManagementClass mc = new ManagementClass(myScope, mypath, null);

            object oValue = GetValue(mc, RegHive.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "CSDVersion");
            Console.WriteLine(oValue.ToString());
        }

        public static object GetValue(ManagementClass mc, RegHive hDefKey, string sSubKeyName, string sValueName)
        {
            RegType rType = GetValueType(mc, hDefKey, sSubKeyName, sValueName);

            ManagementBaseObject inParams = mc.GetMethodParameters("GetStringValue");
            inParams["hDefKey"] = hDefKey;
            inParams["sSubKeyName"] = sSubKeyName;
            inParams["sValueName"] = sValueName;

            object oValue = null;

            switch (rType)
            {
                case RegType.REG_SZ:
                    ManagementBaseObject outParams = mc.InvokeMethod("GetStringValue", inParams, null);

                    if (Convert.ToUInt32(outParams["ReturnValue"]) == 0)
                    {
                        oValue = outParams["sValue"];
                    }
                    else
                    {
                        // GetStringValue call failed
                    }
                    break;

                case RegType.REG_EXPAND_SZ:
                    outParams = mc.InvokeMethod("GetExpandedStringValue", inParams, null);

                    if (Convert.ToUInt32(outParams["ReturnValue"]) == 0)
                    {
                        oValue = outParams["sValue"];
                    }
                    else
                    {
                        // GetExpandedStringValue call failed
                    }
                    break;

                case RegType.REG_MULTI_SZ:
                    outParams = mc.InvokeMethod("GetMultiStringValue", inParams, null);

                    if (Convert.ToUInt32(outParams["ReturnValue"]) == 0)
                    {
                        oValue = outParams["sValue"];
                    }
                    else
                    {
                        // GetMultiStringValue call failed
                    }
                    break;

                case RegType.REG_DWORD:
                    outParams = mc.InvokeMethod("GetDWORDValue", inParams, null);

                    if (Convert.ToUInt32(outParams["ReturnValue"]) == 0)
                    {
                        oValue = outParams["uValue"];
                    }
                    else
                    {
                        // GetDWORDValue call failed
                    }
                    break;

                case RegType.REG_BINARY:
                    outParams = mc.InvokeMethod("GetBinaryValue", inParams, null);

                    if (Convert.ToUInt32(outParams["ReturnValue"]) == 0)
                    {
                        oValue = outParams["uValue"] as byte[];
                    }
                    else
                    {
                        // GetBinaryValue call failed
                    }
                    break;
            }

            return oValue;
        }

        public static RegType GetValueType(ManagementClass mc, RegHive hDefKey, string sSubKeyName, string sValueName)
        {
            ManagementBaseObject inParams = mc.GetMethodParameters("EnumValues");
            inParams["hDefKey"] = hDefKey;
            inParams["sSubKeyName"] = sSubKeyName;

            ManagementBaseObject outParams = mc.InvokeMethod("EnumValues", inParams, null);

            if (Convert.ToUInt32(outParams["ReturnValue"]) == 0)
            {
                string[] sNames = outParams["sNames"] as String[];
                int[] iTypes = outParams["Types"] as int[];

                for (int i = 0; i &lt; sNames.Length; i++)
                {
                    if (sNames[i] == sValueName)
                    {
                        return (RegType)iTypes[i];
                    }
                }
                // value not found
            }
            else
            {
                // EnumValues call failed
            }
            // Things have fallen apart and EnumValues didn't get us what we wanted so assume it's a string
            return RegType.REG_SZ;
        }
    }
}
</code></pre>
