#c# #visual-studio-2010 #registry #32bit-64bit
#c# #visual-studio-2010 #реестр #32-64-битный
Вопрос:
Недавно я перешел на 64-разрядную машину W7 с VS 2010. Мой проект настроен на запуск Any CPU
. Когда я изменил это, чтобы оно было нацелено на x86
, я заметил, что некоторые из моих вызовов реестра больше не работают.
Я пытаюсь прочитать ProductID
поле следующим образом:
RegistryKey windowsNTKey = Registry.LocalMachine.OpenSubKey(@"SoftwareMicrosoftWindows NTCurrentVersion");
object productID = windowsNTKey.GetValue("ProductId");
productID
всегда null
при запуске в режиме x86, при запуске на «любом процессоре» он работает правильно. Что здесь происходит?
Комментарии:
1. Это — чтение из другой области реестра. Однако я не знаю, какой лучший способ работать с этим.
2. @Rup — Как мне это обойти?
Ответ №1:
Некоторые разделы реестра перенаправляются WOW64. Дополнительная информация по этому вопросу доступна в MSDN http://msdn.microsoft.com/en-us/library/aa384232 (v = против 85).aspx
Если вы действительно хотите всегда обращаться к узлу x64 (.Net4) :
RegistryKey localMachine = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey windowsNTKey = localMachine.OpenSubKey(@"SoftwareMicrosoftWindows NTCurrentVersion");
object productID = windowsNTKey.GetValue("ProductId");
Комментарии:
1. ` RegistryKey. OpenBaseKey` для меня не существует… У меня есть только
RegistryKey.OpenRemoteBaseKey
? Яusing Microsoft.Win32;
так и не могу понять, почему?2. @Chris единственное различие, которое я вижу между двумя методами доступа, заключается в том, что
OpenbaseKey
неComVisible
3. Использование
OpenRemoteBaseKey
не позволяет мне передаватьRegistryView
перечисление в качестве аргумента, нужно ли ссылаться на специальную сборку?4. Ах… Я ориентируюсь на 3.5, эти функции доступны только в .NET 4
Ответ №2:
Этот код получит идентификатор для всех видов архитектур ОС и программных архитектур. Можно было бы написать короче, но мне нравится удобочитаемость
static string GetProductId()
{
RegistryKey localMachine = null;
if (Environment.Is64BitOperatingSystem)
{
localMachine = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
}
else
{
localMachine = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry32);
}
RegistryKey windowsNTKey = localMachine.OpenSubKey(@"SoftwareMicrosoftWindows NTCurrentVersion");
return windowsNTKey.GetValue("ProductId").ToString();
}
Комментарии:
1. «Если вы запрашиваете 64-разрядное представление в 32-разрядной операционной системе, возвращаемые ключи будут в 32-разрядном представлении». msdn.microsoft.com/fr-fr/library /…
Ответ №3:
В win64 некоторые разделы реестра 32-разрядного приложения хранятся в SoftwareWow6432Node
подразделе.
Если вы хотите переключиться на 64-разрядный ключ, вы можете использовать RegistryView enum в качестве параметра RegistryKey.OpenBaseKey
Лично для того, чтобы код всегда работал в главном разделе реестра (не WoW6432), я использую такую конструкцию:
RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32)