When trying to retrieve the value of a registry key from a remote machine for a key that has spaces using WMI in C# (Reason for using WMI: Authentication and Impersonation needed), the GetStringValue returns null but when the key doesn't have spaces, it works perfectly. Using either the @ notation or standard " notation for strings didn't help. I tried enclosing the key in double-quotes. Didn't help either.
Here's the code I have written:
public static string GetRemoteRegistryValue(string MachineName, string username, string password)
{
string regValue = string.Empty;
ConnectionOptions opt = new ConnectionOptions();
opt.Impersonation = ImpersonationLevel.Impersonate;
opt.EnablePrivileges = true;
opt.Username = username;
opt.Password = password;
opt.Impersonation = ImpersonationLevel.Impersonate;
opt.EnablePrivileges = true;
try
{
ManagementPath p = new ManagementPath("\\\\" + MachineName + "\\root\\cimv2");
ManagementScope msc = new ManagementScope(p, opt);
msc.Connect();
string softwareRegLoc = "\"SOFTWARE\\VMware, Inc.\\VMware Drivers\"";
//string softwareRegLoc = @"""SOFTWARE\SAP BusinessObjects\Suite XI 4.0\Config Manager""";
ManagementClass registry = new ManagementClass(msc, new ManagementPath("StdRegProv"), null);
ManagementBaseObject inParams = registry.GetMethodParameters("GetStringValue");
inParams["hDefKey"] = 0x80000002;//HKEY_LOCAL_MACHINE
inParams["sSubKeyName"] = softwareRegLoc;
inParams["sValueName"] = "VmciHostDevInst";
// Read Registry Key Names
ManagementBaseObject outParams = registry.InvokeMethod("GetStringValue", inParams, null);
if (outParams.Properties["sValue"].Value != null)
{
regValue = outParams.Properties["sValue"].Value.ToString();
}
}
catch (ManagementException Ex)
{
}
catch (System.UnauthorizedAccessException Ex)
{
}
catch (Exception Ex)
{
}
return regValue;
}
What is the solution for this issue?
Okay, two points here:
You shouldn't use quotation marks. So, replace "\"SOFTWARE\\VMware, Inc.\\VMware Drivers\""
with "SOFTWARE\\VMware, Inc.\\VMware Drivers"
.
The path that you're trying to access belongs to the 64-bit provider. In order to be able to access it (by default), your application needs to have its Platform Target set to x64
. Otherwise, your application would be trying to access the HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\VMware, Inc.\VMware Drivers
path, which probably doesn't exist.
Removing the quotation marks and targeting x64
worked just fine for me and I got the value of the exact path mentioned in the question.
If your Platform Target is set to x86
(or Any CPU
with the Prefer 32-bit
checkbox ticked) and you don't want to change it to x64
, then you have to force WMI to access the 64-bit Registry Hive. Check the documentation for more info.
Here's a full example:
public static string GetRemoteRegistryValue(string MachineName, string username, string password)
{
string regValue = string.Empty;
ConnectionOptions opt = new ConnectionOptions();
opt.Impersonation = ImpersonationLevel.Impersonate;
opt.EnablePrivileges = true;
opt.Username = username;
opt.Password = password;
opt.Impersonation = ImpersonationLevel.Impersonate;
opt.EnablePrivileges = true;
try
{
ManagementPath p = new ManagementPath("\\\\" + MachineName + "\\root\\cimv2");
ManagementScope msc = new ManagementScope(p, opt);
msc.Connect();
string softwareRegLoc = "SOFTWARE\\VMware, Inc.\\VMware Drivers";
ManagementClass registry = new ManagementClass(msc, new ManagementPath("StdRegProv"), null);
ManagementBaseObject inParams = registry.GetMethodParameters("GetStringValue");
inParams["hDefKey"] = 0x80000002;//HKEY_LOCAL_MACHINE
inParams["sSubKeyName"] = softwareRegLoc;
inParams["sValueName"] = "VmciHostDevInst";
ManagementNamedValueCollection objCtx = new ManagementNamedValueCollection();
objCtx.Add("__ProviderArchitecture", 64);
objCtx.Add("__RequiredArchitecture", true);
InvokeMethodOptions options = new InvokeMethodOptions(objCtx, TimeSpan.MaxValue);
// Read Registry Key Names
ManagementBaseObject outParams = registry.InvokeMethod("GetStringValue", inParams, options);
if (outParams.Properties["sValue"].Value != null)
{
regValue = outParams.Properties["sValue"].Value.ToString();
}
}
catch (ManagementException Ex)
{
throw;
}
catch (System.UnauthorizedAccessException Ex)
{
throw;
}
catch (Exception Ex)
{
throw;
}
return regValue;
}
The code above returned the value of VmciHostDevInst
while the app is targeting x86
.
User contributions licensed under CC BY-SA 3.0