Как я могу получить доступ к информации о кустах в 64-битном реестре из приложения, работающего в 32-битном режиме на 64-битной машине (WOW), используя WMI через C # - PullRequest
4 голосов
/ 14 ноября 2009

Я думаю, что вопрос действительно подводит итог тому, что я пытаюсь сделать. Вот код, который я использую. Это работает в любом сценарии, кроме случаев, когда мое приложение работает в 32-битном режиме на 64-битной машине. Независимо от того, как я играю с флагами __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";
      }
 }

Ответы [ 3 ]

7 голосов
/ 08 февраля 2010

Я думаю, что нет необходимости запускать отдельный процесс. Я смог получить доступ к 64-битному реестру удаленной машины из 32-битного процесса. В приведенном выше примере я непосредственно добавил параметры в область вместо установки их в параметрах вызова.

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

Также следует отметить, что в .net 4 теперь есть параметр (RegistryView) в функции OpenRemoteBaseKey, см. В msdn здесь

2 голосов
/ 15 ноября 2009

Вам необходимо открыть ключи с установленным флагом KEY_WOW64_64KEY. Документация MSDN хорошо описывает это.

Обратите внимание, в частности, что вы все еще просто запрашиваете HKLM / Software или подобное. Вы не должны пытаться пройти через редиректоры WoW6432Node, иначе вы застрянете в цикле! Более подробная информация по этой теме: здесь

1 голос
/ 21 января 2010

Я решил эту проблему, запустив отдельный процесс, который работает в собственном 64-разрядном режиме. Этот процесс может легко получить доступ к обоим ульям.

...