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

发布于 2024-08-11 08:04:12 字数 1746 浏览 2 评论 0原文

我认为这个问题确实概括了我正在尝试做的事情。这是我正在使用的代码。它适用于所有场景,除非我的应用程序在 64 位计算机上以 32 位模式运行。无论我如何使用 __ProviderArchitecture 和 __RequiredArchitecture 标志,我似乎总是只能访问配置单元的 32 位部分(WOW6432Node)

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";
      }
 }

I think the question really sums up what i'm trying to do. Here is the code that i'm using. It works in every scenario except if my application is running in 32 bit mode on a 64 bit machine. No matter how I play arround with the __ProviderArchitecture and __RequiredArchitecture flags, i can always only seem to access the 32 bit section of the hive (WOW6432Node)

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";
      }
 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绾颜 2024-08-18 08:04:12

我认为没有必要启动单独的流程。我能够从 32 位进程访问远程计算机的 64 位注册表。在上面的示例中,我已将选项直接添加到范围,而不是在调用选项中设置它们。

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

还需要注意的是,在 .net 4 中,OpenRemoteBaseKey 函数现在有一个参数 (RegistryView),请参见 msdn 此处

I think there is no need to launch a separate process. I was able to access the 64bits registry of a remote machine from a 32bits process. In the sample you have above I've added the options to the scope directly, instead of setting them in the invoke options.

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

It is also to be noted that in .net 4 there is now a parameter (RegistryView) on the OpenRemoteBaseKey function see on msdn here

您需要打开设置了 KEY_WOW64_64KEY 标志的密钥。 MSDN 文档很好地介绍了这一点。

请特别注意,您仍然只要求 HKLM/软件或类似软件。您一定不要尝试通过 WoW6432Node 重定向器,否则您将陷入循环!有关该主题的更多详细信息,请参见此处

You need to open keys with the KEY_WOW64_64KEY flag set. The MSDN documentation covers this well.

Note in particular that you still just ask for HKLM/Software or similar. You mustn't try to go through the WoW6432Node redirectors, otherwise you'll get stuck in a loop! More details on that topic are here

雨后咖啡店 2024-08-18 08:04:12

我通过启动一个在本机 64 位中运行的单独进程解决了这个问题。这个过程可以轻松访问两个蜂巢。

I've solved this by launching a seperate process that runs in native 64 bit. This process can easily access both hives.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文