RegNotifyChangeKeyValue 函数 (winreg.h)
通知调用方对指定注册表项的属性或内容的更改。
语法
LSTATUS RegNotifyChangeKeyValue(
[in] HKEY hKey,
[in] BOOL bWatchSubtree,
[in] DWORD dwNotifyFilter,
[in, optional] HANDLE hEvent,
[in] BOOL fAsynchronous
);
参数
[in] hKey
打开的注册表项的句柄。 此句柄由 RegCreateKeyEx 或 RegOpenKeyEx 函数返回。 也可以是以下 预定义键之一:
HKEY_CLASSES_ROOTHKEY_CURRENT_CONFIGHKEY_CURRENT_USERHKEY_LOCAL_MACHINEHKEY_USERS 此参数必须是本地句柄。 如果使用远程句柄调用 RegNotifyChangeKeyValue ,则返回ERROR_INVALID_HANDLE。
密钥必须已使用KEY_NOTIFY访问权限打开。 有关详细信息,请参阅 注册表项安全和访问权限。
[in] bWatchSubtree
如果此参数为 TRUE,则函数将报告指定键及其子项中的更改。 如果参数为 FALSE,则函数仅报告指定键中的更改。
[in] dwNotifyFilter
一个 值,该值指示应报告的更改。 此参数可使用以下一个或多个值。
[in, optional] hEvent
事件的句柄。 如果 fAsynchronous 参数为 TRUE,则函数将立即返回 ,并通过发出此事件信号来报告更改。 如果 fAsynchronous 为 FALSE,则忽略 hEvent 。
[in] fAsynchronous
如果此参数为 TRUE,则函数将立即返回并通过向指定事件发出信号来报告更改。 如果此参数为 FALSE,则函数在发生更改之前不会返回 。
如果 hEvent 未指定有效的事件, 则 fAsynchronous 参数不能为 TRUE。
返回值
如果函数成功,则返回值为 ERROR_SUCCESS。
如果函数失败,则返回值为 Winerror.h 中定义的非零错误代码。 可以将 FormatMessage 函数与 FORMAT_MESSAGE_FROM_SYSTEM 标志结合使用来获取错误的常规说明。
注解
此函数检测单个更改。 调用方收到通知事件后,应再次调用 函数以接收下一个通知。
如果指定的键已关闭,则会向事件发出信号。 这意味着,应用程序不应依赖于从事件的等待操作返回后打开的密钥。
Windows 8 中引入 的 REG_NOTIFY_THREAD_AGNOSTIC 标志允许对 ThreadPool 线程使用 RegNotifyChangeKeyValue 。
如果调用 RegNotifyChangeKeyValue 的线程退出,则会发出事件信号。 若要继续监视键值的其他更改,请再次从另一个线程调用 RegNotifyChangeKeyValue 。
除了设置了 REG_NOTIFY_THREAD_AGNOSTIC 的 RegNotifyChangeKeyValue 调用之外,必须在持久性线程上调用此函数。 如果调用线程来自线程池且不是永久性的,则每次线程终止时都会发出事件信号,而不仅仅是在注册表发生更改时发出信号。 若要确保结果准确,请使用 SetThreadpoolCallbackPersistent 函数在持久线程中运行线程池工作,或使用 CreateThread 函数创建自己的线程。 (对于原始线程池 API,请使用 QueueUserWorkItem 函数指定WT_EXECUTEINPERSISTENTTHREAD。)
不应多次调用此函数,其 hKey 值相同,但 bWatchSubtree 和 dwNotifyFilter 参数的值不同。 函数将成功,但将忽略更改。 若要更改
watch参数,必须首先通过调用 RegCloseKey 关闭键句柄,通过调用 RegOpenKeyEx 重新打开密钥句柄,然后使用新参数调用 RegNotifyChangeKeyValue。
每次进程使用相同的参数集调用 RegNotifyChangeKeyValue 时,它都会建立另一个等待操作,从而造成资源泄漏。 因此,检查,在上一个等待操作完成之前,不会使用相同的参数调用 RegNotifyChangeKeyValue。
若要更详细地监视注册表操作,请参阅 注册表。
Windows XP/2000: 为特定键句柄调用 RegNotifyChangeKeyValue 时,只要密钥句柄有效,更改通知就会出现。 这会导致第二次调用 RegNotifyChangeKeyValue 立即返回,前提是第一次调用和第二次调用之间发生任何更改。 如果异步使用函数,则在此期间发生任何更改时,将立即向传递的事件句柄发出信号。
示例
以下程序演示如何使用 RegNotifyChangeKeyValue。
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
//void main(int argc, char *argv[])
void __cdecl _tmain(int argc, TCHAR *argv[])
{
DWORD dwFilter = REG_NOTIFY_CHANGE_NAME |
REG_NOTIFY_CHANGE_ATTRIBUTES |
REG_NOTIFY_CHANGE_LAST_SET |
REG_NOTIFY_CHANGE_SECURITY;
HANDLE hEvent;
HKEY hMainKey;
HKEY hKey;
LONG lErrorCode;
// Display the usage error message.
if (argc != 3)
{
_tprintf(TEXT("Usage: notify [HKLM|HKU|HKCU|HKCR|HCC] [<subkey>]\n"));
return;
}
// Convert parameters to appropriate handles.
if (_tcscmp(TEXT("HKLM"), argv[1]) == 0) hMainKey=HKEY_LOCAL_MACHINE;
else if(_tcscmp(TEXT("HKU"), argv[1]) == 0) hMainKey=HKEY_USERS;
else if(_tcscmp(TEXT("HKCU"), argv[1]) == 0) hMainKey=HKEY_CURRENT_USER;
else if(_tcscmp(TEXT("HKCR"), argv[1]) == 0) hMainKey=HKEY_CLASSES_ROOT;
else if(_tcscmp(TEXT("HCC"), argv[1]) == 0) hMainKey=HKEY_CURRENT_CONFIG;
else
{
_tprintf(TEXT("Usage: notify [HKLM|HKU|HKCU|HKCR|HCC] [<subkey>]\n"));
return;
}
// Open a key.
lErrorCode = RegOpenKeyEx(hMainKey, argv[2], 0, KEY_NOTIFY, &hKey);
if (lErrorCode != ERROR_SUCCESS)
{
_tprintf(TEXT("Error in RegOpenKeyEx (%d).\n"), lErrorCode);
return;
}
// Create an event.
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (hEvent == NULL)
{
_tprintf(TEXT("Error in CreateEvent (%d).\n"), GetLastError());
return;
}
// Watch the registry key for a change of value.
lErrorCode = RegNotifyChangeKeyValue(hKey,
TRUE,
dwFilter,
hEvent,
TRUE);
if (lErrorCode != ERROR_SUCCESS)
{
_tprintf(TEXT("Error in RegNotifyChangeKeyValue (%d).\n"), lErrorCode);
return;
}
// Wait for an event to occur.
_tprintf(TEXT("Waiting for a change in the specified key...\n"));
if (WaitForSingleObject(hEvent, INFINITE) == WAIT_FAILED)
{
_tprintf(TEXT("Error in WaitForSingleObject (%d).\n"), GetLastError());
return;
}
else _tprintf(TEXT("\nChange has occurred.\n"));
// Close the key.
lErrorCode = RegCloseKey(hKey);
if (lErrorCode != ERROR_SUCCESS)
{
_tprintf(TEXT("Error in RegCloseKey (%d).\n"), GetLastError());
return;
}
// Close the handle.
if (!CloseHandle(hEvent))
{
_tprintf(TEXT("Error in CloseHandle.\n"));
return;
}
}
要求
最低受支持的客户端 | Windows 2000 Professional [仅限桌面应用] |
最低受支持的服务器 | Windows 2000 Server [仅限桌面应用] |
目标平台 | Windows |
标头 | winreg.h (包括 Windows.h) |
Library | Advapi32.lib |
DLL | Advapi32.dll |