RegNotifyChangeKeyValue 函數 (winreg.h)

通知呼叫者指定登錄鍵的屬性或內容變更。

語法

LSTATUS RegNotifyChangeKeyValue(
  [in]           HKEY   hKey,
  [in]           BOOL   bWatchSubtree,
  [in]           DWORD  dwNotifyFilter,
  [in, optional] HANDLE hEvent,
  [in]           BOOL   fAsynchronous
);

Parameters

[in] hKey

開啟登錄機碼的句柄。 此句柄由 RegCreateKeyEx 或 RegOpenKeyEx 函式回傳。 它也可以是以下 預設的鍵之一:

HKEY_CLASSES_ROOT、 HKEY_CURRENT_CONFIG、 HKEY_CURRENT_USER、 HKEY_LOCAL_MACHINE、 HKEY_USERS。

這個參數必須是本地的句柄。 如果用遠端句柄呼叫 RegNotifyChangeKeyValue ,會回傳 ERROR_INVALID_HANDLE。

鑰匙必須是用KEY_NOTIFY通行權開啟的。 欲了解更多資訊,請參閱 註冊金鑰安全與存取權限。

[in] bWatchSubtree

若此參數為真,函式會報告指定鍵及其子鍵的變更。 若參數為 FALSE,函式僅報告指定鍵值的變更。

[in] dwNotifyFilter

一個表示應回報變更的值。 此參數可以是下列其中一或多個值。

價值 Meaning
REG_NOTIFY_CHANGE_NAME
0x00000001L
如果新增或刪除子機碼,請通知呼叫端。
REG_NOTIFY_CHANGE_ATTRIBUTES
0x00000002L
通知呼叫端密鑰屬性的變更,例如安全性描述元資訊。
REG_NOTIFY_CHANGE_LAST_SET
0x00000004L
通知呼叫端對索引鍵值所做的變更。 這包括新增或刪除值,或變更現有的值。
REG_NOTIFY_CHANGE_SECURITY
0x00000008L
通知呼叫端金鑰之安全性描述元的變更。
REG_NOTIFY_THREAD_AGNOSTIC
0x10000000L
表示註冊的存續期間不應與發出 RegNotifyChangeKeyValue 呼叫的執行緒存續時間綁定。
Note 此旗標值僅支援於 Windows 8 及以後版本。
 

[in, optional] hEvent

一個事件的暱稱。 若 fAsynchronous 參數為 TRUE,函式會立即返回,變更會透過此事件進行通報。 若 fAsynchronous 為 FALSE,則忽略 hEvent 。

[in] fAsynchronous

若此參數為 TRUE,函式會立即回傳並透過指定事件來回報變更。 若此參數為 FALSE,函式不會回傳,直到有變更發生。

若 hEvent 未指定有效事件,fAsynchronous 參數不可能是 TRUE。

返回值

如果函式成功,則傳回值會ERROR_SUCCESS。

如果函式失敗,傳回值是 Winerror.h 中定義的非零錯誤碼。 你可以使用 FormatMessage 函式搭配 FORMAT_MESSAGE_FROM_SYSTEM 標誌,取得錯誤的通用描述。

備註

此功能偵測單一變化。 呼叫者收到通知事件後,應再次呼叫該函式以接收下一次通知。

Note 在 Windows NT、Windows 2000 及 Windows XP 呼叫 RegNotifyChangeKeyValue 以呼叫特定金鑰句柄時,只要該金鑰柄有效,變更通知就會持續發生。 若在第一次與第二次呼叫之間的過渡期間有任何變更,則會立即回傳第二次呼叫 RegNotifyChangeKeyValue 。 若 API 是非同步使用,若有任何臨時變更,傳遞的事件句柄會立即收到訊號。
 
此函式無法用來偵測因使用 RegRestoreKey 函式而導致登錄檔變更的情況。

若指定金鑰關閉,事件即被發出信號。 這表示應用程式不應依賴金鑰在事件等待操作返回後仍未開啟。

Windows 8 年引入的 REG_NOTIFY_THREAD_AGNOSTIC 旗標允許使用 RegNotifyChangeKeyValue 用於 ThreadPool 執行緒。

如果呼叫 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針對特定金鑰柄時,只要該金鑰柄有效,變更通知就會持續發生。 若第一次與第二次呼叫之間發生任何變更,第二次呼叫 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 專業版 [僅限桌面應用程式]
支援的最低伺服器 Windows 2000 伺服器 [僅限桌面應用程式]
目標平臺 Windows 作業系統
標頭 winreg.h(包含 Windows.h)
範本庫 Advapi32.lib
DLL Advapi32.dll

另請參閱

RegCloseKey

RegDeleteKey

RegEnumKeyEx

RegEnumValue

RegQueryInfoKey

RegQueryValueEx

登錄功能