views:

783

answers:

3

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";
      }
 }
+1  A: 

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

Sam
I need to do this remotely through WMI. This flag seems to be a remote registry thing which in my case i cannot use. I tried to use the flags listed in http://msdn.microsoft.com/en-us/library/aa393067(VS.85).aspx but those don't seem to work either, which is why i gave the code sample.
Mark
A: 

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

Mark
A: 

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

Guillaume Gros