Как мне прочитать реестр в 32-битном приложении c #, чтобы перенаправление реестра работало в 64-битной Windows 7

Мой босс только что получил Windows 7 и попытался запустить один из наших установщиков, который отлично работает под XP. В Windows 7 установщик запускается без ошибок. Однако он не создает ключи реестра в HKEY_LOCAL_MACHINE \ SOFTWARE {Company} {product}. Эти ключи создаются правильно под XP.

Кто-нибудь сталкивался с этой проблемой? Я подозреваю, что это проблема с правами / безопасностью, но я не уверен, и у меня нет Windows 7, с которой можно было бы поэкспериментировать.

ИЗМЕНИТЬ

Рассматриваемый компьютер - это 64-битная машина с 64-битной Windows. Оказывается, Windows 7 перенаправляет 32-разрядные приложения в HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node {Company} {product}. Проблема в том, что код моего приложения пытается получить доступ к реестру, используя жестко запрограммированное значение, подобное этому:

var t = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\..., "ValueName", DefaultValue);

Итак, мой новый вопрос: как мне получить доступ к реестру, чтобы перенаправление реестра Windows 9 работало?


person ejwipp    schedule 17.02.2010    source источник


Ответы (4)


Если вы используете .NET 4, вы можете специально запросить, чтобы ваш 32-битный (или 64-битный) процесс обращался к 64-битному представлению реестра с помощью метода RegistryKey.OpenBaseKey.

Ср. http://msdn.microsoft.com/en-us/library/microsoft.win32.registrykey.openbasekey.aspx

Вот пример, который считывает значение из 64-битного представления реестра, даже если оно выполняется как часть 32-битного процесса:

var hklm64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
var key = hklm.OpenSubKey(@"SOFTWARE\AcmeSoft\AnvilMaker 1.0");
var value = (string) key.GetValue("Blacksmith Name");

Метод RegistryKey.OpenBaseKey также позволяет вам явно открыть 32-битное представление реестра. Это полезно, если вы пытаетесь пойти другим путем и получить доступ к 32-битному представлению реестра из 64-битного процесса, и вы не хотите явно добавлять «Wow6432Node» в путь реестра.

Например, сегодня мне нужно было удалить дерево подключей в обоих 32-битных и 64-битных представлениях реестра. Сделать это в .NET 4 с одним путем в реестре было просто:

foreach(var view in new[] {RegistryView.Registry32, RegistryView.Registry64})
{
     var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view);
     hklm.DeleteSubKeyTree(@"SOFTWARE\AcmeSoft\SomeKeyWeNoLongerWant", throwOnMissingSubKey: false);
}   

В 64-разрядной версии Windows приведенный выше код удалит из реестра следующие деревья вложенных ключей:

Computer\HKEY_LOCAL_MACHINE\SOFTWARE\AcmeSoft\SomeKeyWeNoLongerWant
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\AcmeSoft\SomeKeyWeNoLongerWant

-Адам

person adamjcooper    schedule 08.11.2011

Покопавшись, я наткнулся на ссылку , в котором описаны правила доступа к реестру для приложений .NET. Моя программа изначально была нацелена на AnyCpu, что заставляет приложение ориентироваться на 64-битный реестр, даже если Windows установила его под Wow6432Node. Установив цель на «x86», моя программа «волшебным образом» начала получать доступ к реестру под узлом Wow6432Node. Иди разберись!

person ejwipp    schedule 17.02.2010

В API C Windows для этого нужно установить для параметра samDesired в вызове RegOpenKeyEx значение KEY_WOW64_64KEY. Это означает, что поиск значения реестра будет отображаться на обычную 64-битную запись, а не на запись WOW32Node. Я не понимаю, как вы могли бы достичь этого в .Net, хотя класс Registry, похоже, не поддерживает эти операции, но, возможно, он предоставляется через новый класс?

person the_mandrill    schedule 17.02.2010

Отражение реестра

Образец кода

person Cj Anderson    schedule 17.02.2010
comment
Я нашел приведенную выше ссылку перед публикацией, но ее нет в .NET. Есть ли способ добиться успеха с помощью управляемого кода? - person ejwipp; 18.02.2010