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
報告する必要がある変更を示す 値。 このパラメーターには、次の 1 つ以上の値を指定できます。
[in, optional] hEvent
イベントのハンドル。 fAsynchronous パラメーターが TRUE の場合、関数は直ちにを返し、このイベントを通知することで変更が報告されます。 fAsynchronous が FALSE の場合、hEvent は無視されます。
[in] fAsynchronous
このパラメーターが TRUE の場合、関数は直ちにを返し、指定したイベントを通知することによって変更を報告します。 このパラメーターが FALSE の場合、関数は変更が発生するまで戻りません。
hEvent で有効なイベントが指定されていない場合、fAsynchronous パラメーターを TRUE にすることはできません。
戻り値
関数が成功した場合、戻り値は ERROR_SUCCESS です。
関数が失敗した場合、戻り値は Winerror.h で定義されている 0 以外のエラー コードです。 FORMAT_MESSAGE_FROM_SYSTEM フラグを指定して FormatMessage 関数を使用すると、エラーの一般的な説明を取得できます。
解説
この関数は、1 つの変更を検出します。 呼び出し元が通知イベントを受信した後、関数をもう一度呼び出して、次の通知を受信する必要があります。
指定したキーが閉じている場合は、イベントが通知されます。 つまり、アプリケーションは、イベントの待機操作から戻った後に開いているキーに依存しないようにする必要があります。
Windows 8 で 導入されたREG_NOTIFY_THREAD_AGNOSTIC フラグを使用すると、ThreadPool スレッドに RegNotifyChangeKeyValue を使用できます。
RegNotifyChangeKeyValue を呼び出したスレッドが終了すると、イベントが通知されます。 キーの値の追加の変更を引き続き監視するには、別のスレッドから RegNotifyChangeKeyValue をもう一度呼び出します。
regNotifyChangeKeyValue 呼び出しがREG_NOTIFY_THREAD_AGNOSTIC設定されている場合を除き、この関数は永続的なスレッドで呼び出す必要があります。 呼び出し元のスレッドがスレッド プールからのものであり、永続的でない場合、レジストリの変更がある場合だけでなく、スレッドが終了するたびにイベントが通知されます。 正確な結果を得るには、 SetThreadpoolCallbackPersistent 関数を使用して永続的なスレッドでスレッド プールの作業を実行するか、 CreateThread 関数を使用して独自のスレッドを作成します。 (元のスレッド プール API の場合は、 QueueUserWorkItem 関数を使用してWT_EXECUTEINPERSISTENTTHREADを指定します)。
この関数は 、hKey の値が同じで 、bWatchSubtree パラメーターと dwNotifyFilter パラメーターの値が異なる複数回呼び出すことはできません。 関数は成功しますが、変更は無視されます。 次を変更するには
パラメーター watch、まず RegCloseKey を呼び出してキー ハンドルを閉じ、RegOpenKeyEx を呼び出してキー ハンドルを再度開き、新しいパラメーターで RegNotifyChangeKeyValue を呼び出す必要があります。
プロセスは、同じパラメーター セットを使用して RegNotifyChangeKeyValue を呼び出すたびに、別の待機操作を確立し、リソース リークを作成します。 したがって、前の待機操作が完了するまで、同じパラメーターで RegNotifyChangeKeyValue を呼び出していないチェック。
レジストリ操作の詳細については、「 レジストリ」を参照してください。
Windows XP/2000: 特定のキー ハンドルに対して RegNotifyChangeKeyValue が呼び出されると、キー ハンドルが有効である限り、変更通知が発生します。 これにより、最初の呼び出しと 2 番目の呼び出しの中間で変更が発生した場合、 RegNotifyChangeKeyValue への 2 回目の呼び出しがすぐに返されます。 関数が非同期的に使用されている場合、中間で変更が発生した場合、渡されたイベント ハンドルはすぐに通知されます。
例
次のプログラムは、 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 |