Функция 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.
Комментарии
Эта функция обнаруживает одно изменение. После того как вызывающий объект получит событие уведомления, он должен снова вызвать функцию, чтобы получить следующее уведомление.
Если указанный ключ закрыт, событие сигнализируется. Это означает, что приложение не должно зависеть от ключа, который открывается после возврата из операции ожидания события.
Флаг REG_NOTIFY_THREAD_AGNOSTIC , представленный в Windows 8, позволяет использовать RegNotifyChangeKeyValue для потоков ThreadPool.
Если поток с именем RegNotifyChangeKeyValue завершает работу, событие сигнализируется. Чтобы продолжить отслеживать дополнительные изменения в значении ключа, снова вызовите RegNotifyChangeKeyValue из другого потока.
За исключением вызовов RegNotifyChangeKeyValue с REG_NOTIFY_THREAD_AGNOSTIC задано, эту функцию необходимо вызывать в постоянных потоках. Если вызывающий поток находится из пула потоков и не является постоянным, событие сообщается при каждом завершении потока, а не только при изменении реестра. Чтобы обеспечить точные результаты, запустите работу пула потоков в постоянном потоке с помощью функции SetThreadpoolCallbackPersistent или создайте собственный поток с помощью функции CreateThread . (Для исходного API пула потоков укажите WT_EXECUTEINPERSISTENTTHREAD с помощью функции QueueUserWorkItem .)
Эту функцию не следует вызывать несколько раз с одинаковым значением для 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 |
Header | winreg.h (включая Windows.h) |
Библиотека | Advapi32.lib |
DLL | Advapi32.dll |