用RegNotifyChangeKeyValue() 設定與登錄機碼長期關聯

來源:互聯網
上載者:User

 

 

 

 

 

        

癥狀RegNotifyChangeKeyValue() API 允許應用程式以接收事件通知的指定登錄機碼和其子項中更改。

在 MicrosoftWindowsNT、 Microsoft Windows 2000 和 MicrosoftWindowsXP 對特定關鍵柄調用 RegNotifyChangeKeyValue() 導致更改通知以繼續使用在發生只要密鑰柄是有效。 這將導致二調用 RegNotifyChangeKeyValue() 回到立即, 如果在第一和第二個調用之間過渡期有發生任何更改。 傳遞事件控制代碼如果正在使用非同步, API 將被通知立即如果發生了任何臨時更改。

Microsoft Windows 98 不不跟蹤的臨時更改。 調用 RegNotifyChangeKeyValue 僅通知您的調用後發生更改。

解決方案您可能不關心臨時更改。 相反, 要只接收通知對將來更改 RegNotifyChangeKeyValue() 調用後發生。

下列方法之一可用於確保不對臨時更改接收通知:

關閉並重新開啟項。 返回新鍵控點未註冊用於更改通知。
使用非同步 RegNotifyChangeKeyValue() 並等待使用 WaitForSingleObject() 零逾時事件上。 這將清除可能臨時通知。 如果發生任何更改, 沒有損害是完成, 像等待與 WAIT_TIMEOUT 立即返回。 然後立即再次調用 API 來捕捉將來更改。

多線程應用程式應使用第二種, 因為它避免了關閉註冊表柄出從下另一個線程可能正在使用它的可能性。

有關樣本實現此二方法, 請參閱本文末尾代碼。

狀態此行為是設計使然。

更多資訊有幾個要處理註冊表更改通知時牢記事項:

當與檔案更改通知 API, RegNotifyChangeKeyValue() 不返回任何指示以什麼在登錄機碼或其子項或值已更改。 以便它可以確定了哪些更改程式必須知道的項或值之前對通知, 狀態。

沒有更改與通知不一對一關聯性。 接收更改通知, 時有實際上可能已大量註冊表更改。

範例程式碼

那些使用者與檔案過更改通知, 知道 FindFirstChangeNotification() 可用於接收目錄中只對將來更改通知。 然後可以使用 FindNextChangeNotification() 接收更改臨時檔案。 確保, 是不丟失通知。 遺憾, 還有沒有內建類似函數的註冊表更改通知。 以下範例程式碼說明如何?這些函數使用二方法 " 解決辦法 " 部分中列出。 實現下列功能:

RegFindFirstChange()
RegFindNextChange()
RegFindCloseChange()

//**********************************************************************// //  This program demonstrates how to work with registry change//  notifications. In particular, it shows how to either receive//  or ignore interim registry changes (for example, those that occur in//  the period between receiving a notification and the next call//  to RegNotifyChangeKeyValue().// //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF//  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED//  TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A//  PARTICULAR PURPOSE.// //  Copyright (C) 1999 Microsoft Corporation. All rights reserved.// //**********************************************************************#include <windows.h>#include <conio.h>#include <stdio.h>#include <tchar.h>// defined constants#define MONITOR_TOPKEY  HKEY_LOCAL_MACHINE#define MONITOR_SUBKEY  TEXT("Software//Temp")// structure used internally by RegFindFirst/NextChange()typedef struct _REG_CHANGE_DATA {   HKEY   hKey;   BOOL   bWatchSubtree;   DWORD  dwNotifyFilter;} REG_CHANGE_DATA, *LPREG_CHANGE_DATA;// function prototypesHANDLE RegFindFirstChange( HKEY hKey, BOOL bWatchSubtree,       DWORD dwNotifyFilter, LPREG_CHANGE_DATA lprcd );BOOL RegFindNextChange( HANDLE hChange, LPREG_CHANGE_DATA lprcd );BOOL RegFindCloseChange( HANDLE hChange );void DisplayError( LPTSTR szAPI, DWORD dwError );//**********************************************************************// //  _tmain() -- becomes main() for ANSI or wmain() for Unicode// //  PURPOSE :     This is the entry point for the program. This function//                contains sample code demonstrating how to use the//                RegFind*() functions implemented below.// //  PARAMETERS:   None// //  RETURN VALUE: None// //**********************************************************************void _tmain( void ) {   DWORD  dwFilter;   LONG   lResult;   HKEY   hKey;   char   ch;   HANDLE hChange    = NULL;   BOOL   bContinue  = TRUE;   REG_CHANGE_DATA   rcd;   // open the key to be monitored   lResult = RegOpenKeyEx( MONITOR_TOPKEY, MONITOR_SUBKEY,          0, KEY_READ, &hKey );   if ( lResult != ERROR_SUCCESS )      DisplayError( "RegOpenKeyEx()", lResult );   __try {      // filter for all registry changes      dwFilter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES            | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY;      while ( bContinue ) {         _tprintf( TEXT("'f' FindFirst; 'n' FindNext; 'q' Quit --> ") );               ch = _getche();         _tprintf( TEXT("/n") );         switch ( ch ) {                        case 'f': case 'F':  // FindFirst                           // close old handle, if it exists               if ( hChange )                  RegFindCloseChange( hChange );               hChange =                      RegFindFirstChange( hKey, TRUE, dwFilter, &rcd );                              if ( hChange == NULL )                  DisplayError( TEXT("RegFindFirstChange()"),                         GetLastError() );               break;            case 'n': case 'N':  // FindNext                           if ( !RegFindNextChange( hChange, &rcd ) )                  DisplayError( TEXT("RegFindNextChange()"),                         GetLastError() );               break;            case 'q': case 'Q':  // Quit               __leave;               break;         }         // wait on the handle, if it exists         if ( hChange ) {            _tprintf( TEXT("Waiting.../n") );            WaitForSingleObject( hChange, INFINITE );            _tprintf( TEXT("Registry change notification received/n") );         }      }   } __finally {      // close change handle, if it exists      if ( hChange )         RegFindCloseChange( hChange );      // close key handle      RegCloseKey( hKey );   }}//**********************************************************************// //  RegFindFirstChange()// //  PURPOSE:      This function begins a registry change notification //                cycle. It will never return a handle that is already //                signaled due to interim change notifications.// //                After a call to RegFindFirstChange(), a call to//                RegFindNextChange() ensures that interim //                notifications are not missed.// //                Since this routine allocates resources, it is //                important that each call is matched up with a //                corresponding RegFindCloseChange() call to free the //                resources.// //  PARAMETERS:   hKey - handle to the key to watch// //                bWatchSubtree - indicates whether or not to receive//                notifications for changes in subkeys// //                dwNotifyFilter - identifies which changes should cause//                notifications to occur// //                lprcd - pointer to a REG_CHANGE_DATA structure used//                to cycle through the changes// //  RETURN VALUE: If the function succeeds, a wait able handle is //                returned. If it fails, NULL is returned and a call to//                GetLastError() identifies why it failed.// //**********************************************************************HANDLE RegFindFirstChange( HKEY hKey, BOOL bWatchSubtree,       DWORD dwNotifyFilter, LPREG_CHANGE_DATA lprcd ) {   LONG lResult;   HANDLE hChange;   lprcd->hKey = hKey;   lprcd->bWatchSubtree = bWatchSubtree;   lprcd->dwNotifyFilter = dwNotifyFilter;   // create event to be signaled when changes occur   hChange = CreateEvent( NULL, TRUE, FALSE, NULL );   // request registry change notifications   lResult = RegNotifyChangeKeyValue( lprcd->hKey,         lprcd->bWatchSubtree, lprcd->dwNotifyFilter,          hChange, TRUE );   if ( lResult != ERROR_SUCCESS ) {      SetLastError( lResult );      return NULL;   }   // It is possible that this key handle has been used to receive   // registry notifications already. Thus, you will wait with a timeout   // of zero to clear interim notifications that might have occurred   if ( WaitForSingleObject( hChange, 0 ) == WAIT_OBJECT_0 ) {      // There were some interim changes; they are cleared now, but      // you must call the API again to request future notifications      lResult = RegNotifyChangeKeyValue( lprcd->hKey,             lprcd->bWatchSubtree, lprcd->dwNotifyFilter,             hChange, TRUE );      if ( lResult != ERROR_SUCCESS ) {         SetLastError( lResult );         return NULL;      }   }   return hChange;}//**********************************************************************// //  RegFindNextChange()// //  PURPOSE:      This function queues the next registry change //                notification in a cycle. It must be preceded by a //                call to RegFindFirstChange().// //                After calling this function, the handle returned by //                RegFindFirstChange() can be waited on again to get //                the next change notification. Using these functions //                in this manner, all interim change notifications will//                be caught.// //  PARAMETERS:   lprcd - pointer to the same REG_CHANGE_DATA structure//                that was initialized with RegFindFirstChange()// //  RETURN VALUE: If the function succeeds, it returns TRUE. If it //                fails, it returns FALSE and a call to GetLastError() //                identifies why it failed.// //**********************************************************************BOOL RegFindNextChange( HANDLE hChange, LPREG_CHANGE_DATA lprcd ) {      LONG lResult;   // reset the event so the handle can be waited on again   if ( !ResetEvent( hChange ) )      return FALSE;      // If you call this function, you want to catch interim changes,    // so simply call the API again.   lResult = RegNotifyChangeKeyValue( lprcd->hKey,         lprcd->bWatchSubtree, lprcd->dwNotifyFilter,          hChange, TRUE );   if ( lResult != ERROR_SUCCESS ) {      SetLastError( lResult );      return FALSE;   }   return TRUE;}//**********************************************************************// //  RegFindCloseChange()// //  PURPOSE:      This function frees the resources allocated by a call//                to RegFindFirstChange().// //  PARAMETERS:   hChange - the waitable handle returned from //                RegFindFirstChange()// //  RETURN VALUE: Always TRUE// //**********************************************************************BOOL RegFindCloseChange( HANDLE hChange ) {   // free event   if ( hChange ) {      CloseHandle( hChange );      hChange = NULL;   }   return TRUE;}//**********************************************************************// //  DisplayError()// //  PURPOSE :     This is a helper function to display an error message //                and exit the process if a function in _tmain() fails.// //  PARAMETERS:   szAPI - the name of the function that failed// //                dwError - the Win32 error code indicating why the//                function failed// //  RETURN VALUE: None// //**********************************************************************void DisplayError( LPTSTR szAPI, DWORD dwError ) {   LPTSTR lpBuffer = NULL;   FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |         FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError,         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),         (LPTSTR) &lpBuffer, 0, NULL );   _tprintf( TEXT("%s failed:/n"), szAPI );   _tprintf( TEXT("    error code = %u/n"), dwError );   _tprintf( TEXT("    message    = %s/n"), lpBuffer );   LocalFree( lpBuffer );      ExitProcess(0);}
http://www.blogbus.com/public/tb.php/1459042/24389391/d1b2d856a57f824b366f60fb09f9d3f6

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.