通过 RegQueryValueEx 和 RegGetValue 获取注册表值时的奇怪行为
Weird behavior when getting registry value via RegQueryValueEx and RegGetValue
我在 c++ 中遇到上述函数的一些问题。两者的行为方式完全相同。这是我看到的过程:
运行 获取注册表值的代码。仔细检查它是否找到了 10000,它应该有(10000 是每个进程对 GDI 对象的默认 windows 限制),确实如此。
使用 regedit 将注册表更改为 10000 以外的内容
运行 代码,但这次它再次找到 10000,而此时它应该找到新值。
无论我怎么尝试,它总是只能找到原始值,而不是
注册表的更新值。
我的东西 noticed/tried:
它对我看过的每个值都这样做,而不仅仅是 GDIProcessHandleQuota。 (它并不总是 return 10000,因为它特定于 GDI 值,它总是 return 任何给定值的预修改值)
即使我重新启动计算机并打开 regedit 来验证密钥,它也会这样做
实际上在 运行 宁步骤 3 之前改变了。
下面代码中的所有结果值(results、results2、results3)都是0,表示ERROR_SUCCESS(笑),这意味着他们没有遇到任何问题。
最后,这是我遇到问题的代码片段:
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
);
当 运行 在 64 位计算机上运行 32 位应用程序时,您的问题很可能是由 WOW64 模拟器引起的。有关详细信息,请参阅 MSDN 文档:
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
标志,或者在使用 RRF_SUBKEY_WOW6464KEY
打开密钥时包含 RRF_SUBKEY_WOW6464KEY
标志RegGetValue()
.
您还打开了具有过多权限的密钥(这可能会在 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)
{
...
}
我在 c++ 中遇到上述函数的一些问题。两者的行为方式完全相同。这是我看到的过程:
运行 获取注册表值的代码。仔细检查它是否找到了 10000,它应该有(10000 是每个进程对 GDI 对象的默认 windows 限制),确实如此。
使用 regedit 将注册表更改为 10000 以外的内容
运行 代码,但这次它再次找到 10000,而此时它应该找到新值。
无论我怎么尝试,它总是只能找到原始值,而不是 注册表的更新值。
我的东西 noticed/tried:
它对我看过的每个值都这样做,而不仅仅是 GDIProcessHandleQuota。 (它并不总是 return 10000,因为它特定于 GDI 值,它总是 return 任何给定值的预修改值)
即使我重新启动计算机并打开 regedit 来验证密钥,它也会这样做 实际上在 运行 宁步骤 3 之前改变了。
下面代码中的所有结果值(results、results2、results3)都是0,表示ERROR_SUCCESS(笑),这意味着他们没有遇到任何问题。
最后,这是我遇到问题的代码片段:
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
);
当 运行 在 64 位计算机上运行 32 位应用程序时,您的问题很可能是由 WOW64 模拟器引起的。有关详细信息,请参阅 MSDN 文档:
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
标志,或者在使用 RRF_SUBKEY_WOW6464KEY
打开密钥时包含 RRF_SUBKEY_WOW6464KEY
标志RegGetValue()
.
您还打开了具有过多权限的密钥(这可能会在 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)
{
...
}