监控注册表键的改动,也可以监控文件夹,用法很简单:

 

 

  1////////////////////////////////////////////////
  2changenotify.h
  
3
  
4#pragma once
  
5
  
6#define WM_MONITER( WM_USER + 1000 )
  
7#define WM_MONITER_EXIT( WM_MONITER + 1 )
  
8#define WM_MONITER_FILE( WM_MONITER + 2 )
  
9
 
10#define ERROR_NOTIFY100000L
 
11#define ERROR_NOTIFY_ALREADY_START( ERROR_NOTIFY + 1 )
 
12
 
13
 14DWORD CALLBACK ChangeMonitorThread( LPVOID pParam );
 15
class CChangeMonitor
 
16{
 17
public:
 18CChangeMonitor();
 19
virtual ~CChangeMonitor();
 20
virtual BOOL StartMoniter( HWND hWnd );
 21
virtual void EndMoniter( void );
 22
protected:
 23
virtual void SendNotify( UINT nMsg );
 24
virtual void CallNextMoniter( void ) = 0;
 25
virtual DWORD WaitNotify( void ) = 0;
 26
protected:
 27HANDLE m_hThread;
 28HWND m_hWnd;
 29DWORD m_dwThreadId;
 
30
 31friend DWORD CALLBACK ChangeMonitorThread( LPVOID pParam );
 
32}
;
 
33
 
34
 
35
 36
class CDirectoryMonitor : public CChangeMonitor
 
37{
 38
public:
 39CDirectoryMonitor();
 
40~CDirectoryMonitor();
 41BOOL StartMoniter( HWND hWnd, LPCTSTR lpPath, BOOL bSubTree 
= TRUE,
 42DWORD dwFilter 
= FILE_NOTIFY_CHANGE_LAST_WRITE );
 43
void EndMoniter( void );
 44
protected:
 45
virtual void CallNextMoniter( void );
 46
virtual DWORD WaitNotify( void );
 47
protected:
 48HANDLE m_hNotify;
 
49}
;
 
50
 
51
 52
class CRegistryMonitor : public CChangeMonitor
 
53{
 54
public:
 55CRegistryMonitor();
 
56~CRegistryMonitor();
 57BOOL StartMoniter( HWND hWnd, HKEY hRoot, LPCTSTR lpSubKey,
 58DWORD dwFilter 
= REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET );
 59
void EndMoniter( void );
 60
protected:
 61
virtual void CallNextMoniter( void );
 62
virtual DWORD WaitNotify( void );
 63
protected:
 64HANDLE m_hNotify;
 65HKEY m_hKey;
 66DWORD m_dwFilter;
 
67}
;
 
68
 
69
 
70
 
71
 
72//////////////////////////////////////////////////////
 73changenotify.cpp
 
74
 
75#include "ChangeNotify.h"
 
76
 77CChangeMonitor::CChangeMonitor( 
void )
 
78: m_hThread( NULL )
 
79, m_hWnd( NULL )
 
80, m_dwThreadId( 0 )
 
81{
 
82}

 
83
 84CChangeMonitor::
~CChangeMonitor( void )
 
85{
 86EndMoniter();
 
87}

 
88
 89BOOL CChangeMonitor::StartMoniter( HWND hWnd )
 
90{
 
91// 判断是否已经启动监视
 92if ( NULL != m_hThread )
 
93{
 94SetLastError( ERROR_NOTIFY_ALREADY_START );
 95TRACE_ERROR( GetLastError() );
 96
return FALSE;
 
97}

 
98// 检查参数
 99if ( NULL == hWnd )
100{
101SetLastError( ERROR_INVALID_PARAMETER );
102TRACE_ERROR( GetLastError() );
103
return FALSE;
104}

105m_hWnd 
= hWnd;
106// 创建监视线程
107m_hThread = CreateThread( NULL, 0, ChangeMonitorThread,
108(LPVOID)this, CREATE_SUSPENDED, &m_dwThreadId );
109ASSERT( NULL 
!= m_hThread );
110
return TRUE;
111}

112
113
void CChangeMonitor::EndMoniter( void )
114{
115// 判断线程是否存在
116if ( m_hThread )
117{
118// 判断线程是否结束
119DWORD dwExitCode;
120VERIFY( GetExitCodeThread( m_hThread, 
&dwExitCode ) );
121
if ( STILL_ACTIVE == dwExitCode )
122{
123ASSERT( m_dwThreadId 
!= 0 );
124// 向线程发送退出消息
125VERIFY( PostThreadMessage( m_dwThreadId, WM_MONITER_EXIT, 00 ) );
126// 等待线程退出
127DWORD dwWaitResult = WaitForSingleObject( m_hThread, 500 );
128ASSERT( WAIT_FAILED 
!= dwWaitResult );
129// 如果等待超时,强制结束线程
130if ( WAIT_TIMEOUT == dwWaitResult )
131{
132VERIFY( TerminateThread( m_hThread, 
0 ) );
133TRACE_ERROR( 
-1 );
134}

135}

136// 关闭线程句柄,将线程相关数据置零
137VERIFY( CloseHandle( m_hThread ) );
138m_hThread 
= NULL;
139m_dwThreadId 
= 0;
140}

141m_hWnd 
= NULL;// 通知窗体置零
142}

143
144
void CChangeMonitor::SendNotify( UINT nMsg )
145{
146// 检查通知窗体句柄是否存在
147ASSERT( m_hWnd != NULL );
148// 发送通知消息
149if ( FALSE == PostMessage( m_hWnd, nMsg, 00 ) )
150{
151TRACE_ERROR( GetLastError() );
152}

153}

154
155DWORD CALLBACK ChangeMonitorThread( LPVOID pParam )
156{
157// 检查参数是否为空
158ASSERT( pParam != NULL );
159// 得到监视器类对象指针
160CChangeMonitor *pChaMon = (CChangeMonitor*)pParam;
161// 检查对象
162ASSERT( pChaMon->m_hThread != NULL );
163ASSERT( pChaMon
->m_hWnd != NULL );
164ASSERT( pChaMon
->m_dwThreadId != 0 );
165// 进入线程消息循环
166MSG msg;// 消息数据结构
167while( FALSE == PeekMessage( &msg, NULL, WM_MONITER_EXIT,
168WM_MONITER_EXIT, PM_REMOVE ) )
169{
170// 以0超时等待通知,直接返回等待结果
171DWORD dwWaitResult = pChaMon->WaitNotify();
172ASSERT( dwWaitResult 
!= WAIT_FAILED );
173
switch( dwWaitResult )// 处理等待结果
174{
175
case WAIT_OBJECT_0:// 通知已接收
176// 向接收者发送通知消息
177pChaMon->SendNotify( WM_MONITER_FILE );
178// 继续下一次等待
179pChaMon->CallNextMoniter();
180
break;
181
case WAIT_TIMEOUT:
182
break;
183}

184Sleep( 
50 );
185}

186
return 0;
187}

188
189
190// CDirectoryMonitor
191
192// 构造函数
193CDirectoryMonitor::CDirectoryMonitor( void )
194: m_hNotify( NULL )
195{
196}

197
198// 析构函数
199CDirectoryMonitor::~CDirectoryMonitor( void )
200{
201}

202
203// 启动监视
204BOOL CDirectoryMonitor::StartMoniter( HWND hWnd, LPCTSTR lpPath,
205 BOOL bSubTree, DWORD dwFilter )
206{
207// 调用父类同名函数
208if ( FALSE == CChangeMonitor::StartMoniter( hWnd ) )
209{
210
return FALSE;
211}

212// 创建监视
213m_hNotify = FindFirstChangeNotification( lpPath, bSubTree, dwFilter );
214
if ( INVALID_HANDLE_VALUE == m_hNotify )
215{
216m_hNotify 
= NULL;
217EndMoniter();
218TRACE_ERROR( GetLastError() );
219
return FALSE;
220}

221// 启动监视线程
222VERIFY( ResumeThread( m_hThread ) );
223
return TRUE;
224}

225
226
void CDirectoryMonitor::EndMoniter( void )
227{
228// 调用父类同名函数
229CChangeMonitor::EndMoniter();
230// 判断通知句柄是否存在
231if ( m_hNotify )
232{
233// 结束通知
234VERIFY( FindCloseChangeNotification( m_hNotify ) );
235m_hNotify 
= NULL;// 通知句柄置零
236}

237}

238
239
void CDirectoryMonitor::CallNextMoniter( void )
240{
241VERIFY( TRUE 
== FindNextChangeNotification( m_hNotify ) );
242}

243
244DWORD CDirectoryMonitor::WaitNotify( 
void )
245{
246
return WaitForSingleObject( m_hNotify, 0 );
247}

248
249
250
251// CRegistryMonitor
252
253// 构造函数
254CRegistryMonitor::CRegistryMonitor( void )
255: m_hKey( NULL )
256, m_hNotify( NULL )
257, m_dwFilter( 0 )
258{
259}

260
261// 析构函数
262CRegistryMonitor::~CRegistryMonitor( void )
263{
264}

265
266// 启动监视
267BOOL CRegistryMonitor::StartMoniter( HWND hWnd, HKEY hRoot,
268LPCTSTR lpSubKey, DWORD dwFilter )
269{
270// 调用父类同名函数
271if ( FALSE == CChangeMonitor::StartMoniter( hWnd ) )
272{
273
return FALSE;
274}

275// 成员数据赋值
276m_dwFilter = dwFilter;
277// 打开注册表键
278LONG lr;
279lr 
= RegOpenKeyEx( hRoot, lpSubKey, 0, KEY_NOTIFY, &m_hKey );
280
if ( ERROR_SUCCESS != lr )
281{
282TRACE_ERROR( lr );
283
return FALSE;
284}

285// 创建通知事件句柄
286m_hNotify = CreateEvent( NULL, FALSE, FALSE, NULL );
287ASSERT( m_hNotify 
== NULL );
288// 开始监视
289CallNextMoniter();
290// 启动监视线程
291VERIFY( ResumeThread( m_hThread ) );
292
return TRUE;
293}

294
295// 结束监视
296void CRegistryMonitor::EndMoniter( void )
297{
298CChangeMonitor::EndMoniter();
299
if ( m_hNotify )
300{
301VERIFY( CloseHandle( m_hNotify ) );
302m_hNotify 
= NULL;
303}

304
if ( m_hKey )
305{
306VERIFY( ERROR_SUCCESS 
== RegCloseKey( m_hKey ) );
307m_hKey 
= NULL;
308}

309}

310
311
void CRegistryMonitor::CallNextMoniter( void )
312{
313ASSERT( m_hKey 
!= NULL );
314ASSERT( m_hNotify 
!= NULL );
315// 创建监视句柄
316VERIFY( ERROR_SUCCESS == RegNotifyChangeKeyValue( m_hKey, TRUE,
317m_dwFilter, m_hNotify, TRUE ) );
318}

319
320DWORD CRegistryMonitor::WaitNotify( 
void )
321{
322
return WaitForSingleObject( m_hNotify, 0 );
323}

324

 

监控目录用法:

首先监控者必须是一个窗体或控件,有句柄,能接受消息。
CDirectoryMonitor dm;
dm.StartMoniter( hWnd, _T("C:\\windows") );

在窗体中响应WM_MONITER_FILE消息就可以了

监控文件:
BOOL ReadDirectoryChangesW(
  HANDLE hDirectory,
  LPVOID lpBuffer,
  DWORD nBufferLength,
  BOOL bWatchSubtree,
  DWORD dwNotifyFilter,
  LPDWORD lpBytesReturned,
  LPOVERLAPPED lpOverlapped,
  LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);