У меня есть 32-битное приложение, которое должно добавить значение в x64-битную часть реестра.
Я хочу сделать это за счет использования regedit.exe -s fileWithKeys.reg
, Однако когда я пытаюсь охватить regedit (в коде приложения я использовал C:\windows\sysnative
каталог), то я получаю 32-битную версию. Мне нужно охватить x64-битную версию инструмента (regedit), чтобы добавить эти ключи в правильный x64-битный узел.
Я обнаружил, что могу смоделировать это, запустив C:\Windows\SysWOW64\cmd.exe
и звонит C:\Windows\regedit.exe
оттуда. Я не могу запустить 64-битную версию, потому что вместо нее работает 32-битная версия regedit.
Как это сделать?
В 64-битной Windows существует так называемое перенаправление файловой системы и реестра. Они существуют для совместимости со старыми приложениями, написанными для 32-битной Windows, и для приложений, разработанных для более старых версий Windows. WoW64 перехватывает все системные вызовы, выполняемые 32-разрядными процессами, так что если мое 32-разрядное приложение, работающее в 64-разрядной версии Windows, вызывает C: \ Windows \ System32, WoW64 прозрачно перенаправляет его на C: \ Windows \ SysWoW64, и т. д. Виртуальный каталог C: \ Windows \ Sysnative указывает на родной версия (64-разрядная версия) каталога, независимо от разрядности потока, ссылающегося на этот путь файловой системы.
Аналогичный механизм существует для реестра, и для этого и предназначен ключ WoW6432Node. Технически я бы назвал их 32-битными и 64-битными Просмотры реестра, если я хочу быть лаконичным ... Или педантичным.
Не так давно я написал код (на C #) для доступа к ключу в собственной (64-битной) части улья из 32-битного процесса. Вот сокращенный фрагмент:
// Accessing 64-bit registry key from 32-bit process
enum RegAccessFlag
{
NONE = 0,
KEY_QUERY_VALUE = 0x0001,
KEY_SET_VALUE = 0x0002,
KEY_CREATE_SUB_KEY = 0x0004,
KEY_ENUMERATE_SUB_KEYS = 0x0008,
KEY_NOTIFY = 0x0010,
KEY_CREATE_LINK = 0x0020,
KEY_WOW64_64KEY = 0x0100, // This is the ticket
KEY_WOW64_32KEY = 0x0200,
KEY_WOW64_RES = 0x0300
}
public static UIntPtr HKEY_LOCAL_MACHINE = new UIntPtr(0x80000002u);
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int RegOpenKeyEx(UIntPtr hkey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult);
static void Main(string[] args)
{
int statusCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE", 0, (int)RegAccessFlag.KEY_WOW64_64KEY | (int)RegAccessFlag.KEY_QUERY_VALUE, out hKey);
}
Конечно, вам все равно нужно прочитать значение из ключа после того, как вы его открыли, или создать новое значение, а затем не забудьте закрыть ключ, когда вы закончите, но это поможет вам начать, если вы захотите написать какой-либо код. .
Но поскольку вы говорите о порождении 32-битного процесса из другого 32-битного процесса, чтобы этот дочерний процесс мог получить доступ к собственному представлению реестра на 64-битной платформе ... вы имеете дело с комбинацией обоих перенаправление файловой системы и перенаправление реестра мешает вам. И В довершение ко всему, regedit.exe - своего рода специальная утилита в этом отношении.
TL; DR: дать C:\Windows\sysnative\regedt32.exe
попытка вместо regedit.exe
.
https://stackoverflow.com/questions/12233396/open-64-bit-regedit-from-32-bit-application
Версия по умолчанию regedit.exe
в 64-битной ОС Windows является 64-битная версия.
Исполняемый файл regedit, расположенный в C:\Windows\SysWOW64
это 32-битная версия, а исполняемый файл в C:\Windows
это 64-битная версия.
Итак ... вот почему вы видите 32-битную версию, когда запускаете ее из SysWOW64
. Потому что ты являются работает 32-битная версия. SysWOW64
- это место, где находится 32-битная версия и откуда она используется (поскольку она запускается 64-битной системой для обеспечения совместимости).
Вы можете проверить / проверить, какую версию regedit вы используете, через наличие Wow6432Node
ключ под HKEY_LOCAL_MACHINE\SOFTWARE
. Когда вы запускаете regedit из C:\Windows
, этот узел будет существовать (он отображает 32-разрядную версию ключей реестра). Если вы запустите regedit из C:\Windows\SysWOW64
этого ключа не будет, потому что вы уже просматриваете 32-битный реестр.
C:\Windows\regedit.exe
<=> 64-битная версия regedit.
C:\Windows\SysWOW64\regedit.exe
<=> 32-битная версия regedit.
Кажется, что "%systemroot%\regedit.exe"
также выполняет какое-то перенаправление.
Начиная с Vista, это работает при использовании 32-разрядной версии. cmd
в 64-битной системе:
"%systemroot%\sysnative\cmd.exe" /c "%systemroot%\regedit.exe"