当试图使用C#中的WMI从远程计算机检索具有空格的注册表项的值时(使用WMI的原因:需要身份验证和模拟(,GetStringValue返回null,但当该注册表项没有空格时,它可以完美地工作。使用@符号或标准";字符串的表示法没有帮助。我试着把钥匙用双引号括起来。也无济于事。
这是我写的代码:
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 = @"""SOFTWARESAP BusinessObjectsSuite XI 4.0Config 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;
}
这个问题的解决方案是什么?
好的,这里有两点:
-
您不应该使用引号。因此,将
""SOFTWARE\VMware, Inc.\VMware Drivers""
替换为"SOFTWARE\VMware, Inc.\VMware Drivers"
。 -
您尝试访问的路径属于64位提供程序。为了能够访问它(默认情况下(,您的应用程序需要将其平台目标设置为
x64
。否则,您的应用程序将尝试访问HKEY_LOCAL_MACHINESOFTWAREWOW6432NodeVMware, Inc.VMware Drivers
路径,该路径可能不存在。
删除引号并以x64
为目标对我来说效果很好,我得到了问题中提到的确切路径的值。
如果您的平台目标设置为x86
(或选中Prefer 32-bit
复选框的Any CPU
(,并且不想将其更改为x64
,则必须强制WMI访问64位注册表配置单元。查看文档以了解更多信息。
下面是一个完整的例子:
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;
}
当应用程序以x86
为目标时,上面的代码返回了VmciHostDevInst
的值。