代码之家  ›  专栏  ›  技术社区  ›  Mark

如何使用WMI通过C从64位计算机(WOW)上以32位模式运行的应用程序访问64位注册表配置单元信息?#

  •  3
  • Mark  · 技术社区  · 16 年前

    我认为这个问题真的总结了我想做的事情。这是我使用的代码。除了我的应用程序在64位机器上以32位模式运行之外,它在每个场景中都能工作。无论我如何使用“providerarchitecture”和“requiredarchitecture”标志进行播放,我始终只能访问配置单元的32位部分(wow6432节点)。

    uint LOCAL_MACHINE = 0x80000002;
    string results = "";
    ConnectionOptions options = new ConnectionOptions();
    options.Impersonation = ImpersonationLevel.Impersonate;
    options.EnablePrivileges = true;
    options.Username = this.txtUser.Text;
    options.Password = this.txtPassword.Text;
    
    ManagementScope myScope = new ManagementScope("\\\\" + this.txtMachine.Text + "\\root\\default", options);
    ManagementPath mypath = new ManagementPath("StdRegProv");
    ManagementClass mc = new ManagementClass(myScope, mypath, null);
    
    ManagementBaseObject inParams = mc.GetMethodParameters("EnumKey");
    inParams["hDefKey"] = LOCAL_MACHINE;
    inParams["sSubKeyName"] = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
    
    ManagementNamedValueCollection objCtx = new ManagementNamedValueCollection();
    objCtx.Add("__ProviderArchitecture", 64);
    objCtx.Add("__RequiredArchitecture", true);
    
    
    InvokeMethodOptions invokeOptions = new InvokeMethodOptions();
    invokeOptions.Context = objCtx;
    ManagementBaseObject outParams = mc.InvokeMethod("EnumKey", inParams, invokeOptions);
    
    inParams = mc.GetMethodParameters("GetStringValue");
    inParams["hDefKey"] = LOCAL_MACHINE;
    
    foreach(string name in (string[])outParams["sNames"])
    {
          inParams["sSubKeyName"] = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" + "\\" + name;
          inParams["sValueName"] = "DisplayName";
          outParams = mc.InvokeMethod("GetStringValue", inParams, invokeOptions);
    
          if (!string.IsNullOrEmpty(((string)outParams["sValue"])))
          {
              results += outParams["sValue"] + "\t";
          }
     }
    
    3 回复  |  直到 15 年前
        1
  •  6
  •   Guillaume Gros    16 年前

    我认为没有必要启动一个单独的过程。我可以访问 遥远的 32位进程的机器。在上面的示例中,我已经将选项直接添加到作用域中,而不是在invoke选项中设置它们。

    myScope.Options.Context.Add("__ProviderArchitecture", 64);
    myScope.Options.Context.Add("__RequiredArchitecture", true);
    

    还需要注意的是,在.NET 4中,openRemoteBaseKey函数上现在有一个参数(registryView),请参见msdn上的。 here

        2
  •  2
  •   Sam Holloway    16 年前

    你需要打开钥匙 KEY_WOW64_64KEY 标志集。这个 MSDN documentation 盖住这口井。

    特别要注意的是,您仍然只需要询问hklm/software或类似产品。你不能试图通过ww6432node重定向器,否则你会陷入一个循环!关于这个主题的更多细节是 here

        3
  •  1
  •   Mark    16 年前

    我通过启动一个单独的进程来解决这个问题,该进程在本机64位中运行。这个过程可以很容易地访问两个蜂箱。

    推荐文章