C# WMI Registry GetStringValue returning null when string is there

1

I am using the following code that I have put together reading other questions here:

        ConnectionOptions oConn = new ConnectionOptions();
        System.Management.ManagementScope scope = new System.Management.ManagementScope(@"\\" + "compname" + @"\root\cimv2", oConn);

        scope.Connect();

        MessageBox.Show("");
        ManagementClass registry = new ManagementClass(scope, new ManagementPath("StdRegProv"), null);
        ManagementBaseObject inParams = registry.GetMethodParameters("GetStringValue");
        inParams["hDefKey"] = 0x80000002;// HKEY_LOCAL_MACHINE;
        inParams["sSubKeyName"] = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI";
        inParams["sValueName"] = "LastLoggedOnDisplayName";


        ManagementBaseObject outParams = registry.InvokeMethod("GetStringValue", inParams, null);


        if (outParams.Properties["sValue"].Value != null)
        {

            MessageBox.Show(outParams.Properties["sValue"].Value.ToString());
        }

However, each time the outParams.Properties["sValue"].Value is returning null, even when I can see the string value is in fact in the registry editor.

If I use the following code to loop through the subkeys:

        string[] subkeys = (string[])mc.InvokeMethod("EnumValues", mbo, null).Properties["sNames"].Value;

        foreach (string strKey in subkeys)
        {
            MessageBox.Show(strKey);
        }

It will only show me one subkey, regardless of the type, and switching EnumValues to GetStringValue causes a path not found error`

Something wonky is going on and maybe another set of eyes can help me see? In the end, I'm just trying to get the LastLoggedOnDisplayName string value in SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI

Any feedback is appreciated

c#
string
registry
wmi
asked on Stack Overflow Apr 22, 2021 by EyeSeeSharp

1 Answer

1

By default your app is 32 bit so will be redirected to the 32 bit registry location on a 64 bit OS:

SOFTWARE\WOW6432Node\Microsoft\...

To force reading the 64 bit value either build as 64 bit or configure your scope as:

System.Management.ManagementScope scope = new System.Management.ManagementScope(@"\\" + "compname" + @"\root\cimv2", oConn);
        
scope.Options.Context.Add("__ProviderArchitecture", 64);
scope.Options.Context.Add("__RequiredArchitecture", true);

scope.Connect();

(I'm assuming your using this code to access remote registries, if that's not the case this can be done more simply: https://docs.microsoft.com/en-us/dotnet/api/microsoft.win32.registry.getvalue)

answered on Stack Overflow Apr 22, 2021 by Alex K.

User contributions licensed under CC BY-SA 3.0