C# 当注册表项在WMI中有空格时,注册表值返回null

C# 当注册表项在WMI中有空格时,注册表值返回null,c#,wmi,C#,Wmi,当尝试从远程计算机检索注册表项的值时,如果该项在C中使用WMI具有空格,则使用WMI的原因:需要验证和模拟,GetStringValue将返回null,但当该项没有空格时,它会正常工作。对字符串使用@符号或标准符号都没有帮助。我试着用双引号把钥匙括起来。也没用 以下是我编写的代码: public static string GetRemoteRegistryValue(string MachineName, string username, string password) { stri

当尝试从远程计算机检索注册表项的值时,如果该项在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 = @"""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;
}
这个问题的解决方案是什么?

好的,这里有两点:

你不应该用引号。因此,请将\SOFTWARE\\VMware,Inc.\\VMware Drivers\替换为SOFTWARE\\VMware,Inc.\\VMware Drivers

您尝试访问的路径属于64位提供程序。为了能够在默认情况下访问它,应用程序需要将其平台目标设置为x64。否则,您的应用程序将尝试访问HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\VMware,Inc.\VMware驱动程序路径,该路径可能不存在

删除引号并瞄准x64对我来说效果很好,我得到了问题中提到的确切路径的值

如果您的平台目标设置为x86或勾选了“首选32位”复选框的任何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的值。

好的,这里有两点:

你不应该用引号。因此,请将\SOFTWARE\\VMware,Inc.\\VMware Drivers\替换为SOFTWARE\\VMware,Inc.\\VMware Drivers

您尝试访问的路径属于64位提供程序。为了能够在默认情况下访问它,应用程序需要将其平台目标设置为x64。否则,您的应用程序将尝试访问HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\VMware,Inc.\VMware驱动程序路径,该路径可能不存在

删除引号并瞄准x64对我来说效果很好,我得到了问题中提到的确切路径的值

如果您的平台目标设置为x86或勾选了“首选32位”复选框的任何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的值。

我目前没有安装Visual Studio,因此无法检查此问题:您是否尝试了下划线?这些异常是否告诉您什么?@LarsTech输出参数。属性返回值为2,没有exception@AStopher我在注册表中没有找到带下划线的键。所以我还并没有试过。@Ashwinharaharan我的意思是代替空格,让VMware,Inc.成为VMware,例如。不知道它是否能工作。我目前没有安装Visual Studio,因此无法检查:您是否尝试了下划线?这些异常是否告诉您什么?@LarsTech outParams.Properties返回值为2,没有exception@AStopher我在注册表中没有找到带下划线的键。所以我还并没有试过。@Ashwinharaharan我的意思是代替空格,让VMware,Inc.成为VMware,例如。但不知道它是否有效。