如何通过 C# 使用 WMI 从 64 位计算机 (WOW) 上以 32 位模式运行的应用程序访问 64 位注册表配置单元信息
我认为这个问题确实概括了我正在尝试做的事情。这是我正在使用的代码。它适用于所有场景,除非我的应用程序在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为没有必要启动单独的流程。我能够从 32 位进程访问远程计算机的 64 位注册表。在上面的示例中,我已将选项直接添加到范围,而不是在调用选项中设置它们。
还需要注意的是,在 .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.
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
我通过启动一个在本机 64 位中运行的单独进程解决了这个问题。这个过程可以轻松访问两个蜂巢。
I've solved this by launching a seperate process that runs in native 64 bit. This process can easily access both hives.