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