我有一个 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。
有办法吗?
答案1
在 64 位 Windows 中,存在所谓的文件系统和注册表重定向。它们存在是为了与为 32 位 Windows 编写的旧应用程序以及为旧版 Windows 设计的应用程序兼容。WoW64 会挂接 32 位进程发出的所有系统调用,这样,如果我在 64 位版 Windows 上运行的 32 位应用程序调用 C:\Windows\System32,WoW64 就会透明地将其重定向到 C:\Windows\SysWoW64,等等。C:\Windows\Sysnative 虚拟目录会将您指向本国的版本(64 位版本)的目录,无论引用该文件系统路径的线程的位数如何。
注册表中也存在类似的机制,这就是 WoW6432Node 键的意义所在。从技术上讲,我将其称为 32 位和 64 位视图如果我想简洁一点...或者迂腐一点的话,注册表。
不久前,我编写了一些代码(使用 C#),用于从 32 位进程中访问 Hive 的本机(64 位)部分中的键。以下是一段节选的代码:
// 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
答案2
regedit.exe
64 位 Windows 操作系统上的默认版本是64 位版本。
中的 regedit 可执行文件C:\Windows\SysWOW64
是 32 位版本,中的可执行文件C:\Windows
是 64 位版本。
所以...这就是为什么你从 运行它时会看到 32 位版本SysWOW64
。因为你是运行 32 位版本。 SysWOW64
是 32 位版本所在的位置,以及它的使用位置(因为它由 64 位系统运行以实现兼容性)。
Wow6432Node
您可以通过下的键是否存在来验证/检查您正在运行哪个版本的 regedit 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。
答案3
似乎这"%systemroot%\regedit.exe"
也起到了某种重定向的作用。
cmd
从 Vista 开始,当您在 64 位系统中运行 32 位时,此方法有效:
"%systemroot%\sysnative\cmd.exe" /c "%systemroot%\regedit.exe"