通过 RegQueryValueEx 和 RegGetValue 获取注册表值时的奇怪行为 [重复]
Posted
技术标签:
【中文标题】通过 RegQueryValueEx 和 RegGetValue 获取注册表值时的奇怪行为 [重复]【英文标题】:Weird behavior when getting registry value via RegQueryValueEx and RegGetValue [duplicate] 【发布时间】:2016-07-21 01:33:02 【问题描述】:我在使用上述函数的 c++ 中遇到了一些问题。两者的行为方式完全相同。这是我看到的过程:
运行代码以获取注册表值。仔细检查它是否找到了 10000,它应该有(10000 是每个进程的 GDI 对象的默认窗口限制),并且确实如此。
使用 regedit 将注册表更改为 10000 以外的值
再次运行代码,但这次它再次找到 10000,而它本应找到新值。
无论我尝试什么,它总是只会找到原始值而不是 注册表的更新值。
我注意到/尝试过的事情:
它对我查看过的每个值都执行此操作,而不仅仅是 GDIProcessHandleQuota。 (它并不总是返回 10000,因为它特定于 GDI 值,它总是返回任何给定值的修改前值)
即使我重新启动计算机并打开 regedit 以验证密钥,它也会这样做 在运行第 3 步之前实际已更改。
以下代码中的所有结果值(results、results2、results3)均为 0,表示 ERROR_SUCCESS (lol),表示它们没有遇到任何问题。
最后,这是我遇到问题的代码 sn-p:
HKEY hKey;
//open the key for viewing in RegQueryValueEx, store opened handle in hkey
LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
0,
KEY_ALL_ACCESS,
&hKey);
DWORD dwReturn;
DWORD dwBufSize = sizeof(DWORD);
//after this line executes, dwReturn should have the DWORD data of the specified registry key/valuename
LONG result2 = RegQueryValueEx(hKey,
"GDIProcessHandleQuota",
0,
0,
reinterpret_cast<LPBYTE>(&dwReturn),
&dwBufSize);
DWORD value;
DWORD size = sizeof(DWORD);
//after this executes, value should contain the DWORD data of the specified registry key/valuename
LONG result3 = RegGetValue(hKey,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
"GDIProcessHandleQuota",
RRF_RT_ANY,
NULL,
&value,
&size
);
【问题讨论】:
你是如何编译你的程序的——32位还是64位?如果是 32 位,您的程序实际上是在 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Windows @The Dark 它正在被编译为 Win32。即使它被告知我明确给出的路径,该位置是否正确? 对不起 - 我在你输入的时候编辑了我的评论 - 检查 Wow6432Node 键 有没有办法强制程序查看其他位置?为什么首先有2个位置?哪个是键的“正确”值? (也就是我应该看哪一个) 这里有一种读取其他位置的方法:***.com/questions/11808462/… - 它是 c#,但想法是一样的。有两个位置可以将 32 位和 64 应用程序分开,所以我想作为 32 位应用程序,您应该不理会它并从 Wow6432Node 键中读取。或者,您可以更改为 64 位应用程序。 【参考方案1】:在 64 位机器上运行 32 位应用程序时,您的问题很可能是由 WOW64 模拟器引起的。有关详细信息,请参阅 MSDN 文档:
Registry Redirector
Registry Keys Affected by WOW64
32-bit and 64-bit Application Data in the Registry
Accessing an Alternate Registry View
要在 32 位应用程序中打开 64 位密钥,您需要在使用 RegOpenKeyEx()
打开密钥时包含 KEY_WOW64_64KEY
标志,或者在使用 RegGetValue()
打开密钥时包含 RRF_SUBKEY_WOW6464KEY
标志。
您还打开了具有太多权限的密钥(这可能会在 UAC 下启动 Registry Virtualization,但在此示例中您正在访问的特定密钥上禁用了此功能,但您应该注意这一点)。 KEY_ALL_ACCESS
仅适用于管理员用户。大多数用户对 HKLM 没有写访问权限,只有只读访问权限,因此非管理员使用 KEY_ALL_ACCESS
打开密钥将失败。始终请求您实际需要的最低权限。在这种情况下,打开KEY_QUERY_VALUE
访问的密钥。
您还使用错误的参数值调用RegGetValue()
。
试试类似的方法:
HKEY hKey;
//open the key for viewing in RegQueryValueEx, store opened handle in hkey
LONG result = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
0,
KEY_QUERY_VALUE | KEY_WOW64_64KEY,
&hKey);
if (result != ERROR_SUCCESS)
...
else
DWORD value;
DWORD size = sizeof(DWORD);
//after this line executes, value should have the DWORD data of the specified registry key/valuename
result = RegQueryValueEx(
hKey,
"GDIProcessHandleQuota",
0,
0,
reinterpret_cast<LPBYTE>(&value),
&size);
if (result != ERROR_SUCCESS)
...
size = sizeof(DWORD);
//after this executes, value should contain the DWORD data of the specified registry key/valuename
result = RegGetValue(
hKey,
NULL,
"GDIProcessHandleQuota",
RRF_RT_REG_DWORD,
NULL,
&value,
&size);
if (result != ERROR_SUCCESS)
...
RegCloseKey(hKey);
或者:
DWORD value;
DWORD size = sizeof(DWORD);
//after this executes, value should contain the DWORD data of the specified registry key/valuename
LONG result = RegGetValue(
HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
"GDIProcessHandleQuota",
RRF_RT_REG_DWORD | RRF_SUBKEY_WOW6464KEY,
NULL,
&value,
&size);
if (result != ERROR_SUCCESS)
...
【讨论】:
以上是关于通过 RegQueryValueEx 和 RegGetValue 获取注册表值时的奇怪行为 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
RegQueryValueEx 返回 ERROR_SUCCESS 但它没有给我数据缓冲区。为啥?
使用RegQueryValueEx作为可能为REG_DWORD或REG_SZ的注册表值