Chinaunix首页 | 论坛 | 博客
  • 博客访问: 8320828
  • 博文数量: 1413
  • 博客积分: 11128
  • 博客等级: 上将
  • 技术积分: 14685
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-13 10:03
个人简介

follow my heart...

文章分类

全部博文(1413)

文章存档

2013年(1)

2012年(5)

2011年(45)

2010年(176)

2009年(148)

2008年(190)

2007年(293)

2006年(555)

分类:

2007-02-28 13:16:45

[点评:前面也有个相关的例子,是用线程来监控的,相比而言,这个例子简单明了容易理解多了.]

Delphi自带的TRegistry类只能实现注册表的基本操作,如果我们要实时监视注册表的变化或者扫描注册表特定项下的所有子项,TRegistry类就无能为力了。

监视注册表相关项的改变要用到一个API:RegNotifyChangeKeyValue。

LONG RegNotifyChangeKeyValue(

HKEY hKey, // 要监视的一个项的句柄

BOOL bWatchSubtree, // 是否监视此项的子键

DWORD dwNotifyFilter, // 监视哪些变化

HANDLE hEvent, // 接受注册表变化事件的事件对象句柄

BOOL fAsynchronous // 注册表变化前报告还是注册表变化后才报告

);

注意上面的hEvent是接受注册表变化事件的事件对象句柄,我们要用API:CreateEvent来创建一个系统事件对象。

HANDLE CreateEvent(

LPSECURITY_ATTRIBUTES lpEventAttributes, // SECURITY_ATTRIBUTES结构

BOOL bManualReset, // 是否自动重置

BOOL bInitialState, // 是否设置初始状态

LPCTSTR lpName // 事件对象的名称

);

新建一个工程,添加一个ListBox,两个Button。

//先写个监视注册表的例子

//监视HKEY_CURRENT_USER\Software项下所有子键

procedure TForm1.Button1Click(Sender: TObject);

var

hNotify : THandle;

hKeyx : HKEY;

dwRes : DWORD;

begin

hNotify := CreateEvent( nil, //不使用SECURITY_ATTRIBUTES结构

FALSE, //不自动重置

TRUE, //设置初始状态

'RegistryNotify' //事件对象的名称

);

if hNotify = 0 then

begin

Showmessage('CreateEvent failed.');

exit;

end;

if RegOpenKeyEx( HKEY_CURRENT_USER, //跟键

'Software', //子键

0, //reserved

KEY_NOTIFY, //监视用

hKeyx //保存句柄

) <> ERROR_SUCCESS then

begin

CloseHandle( hNotify );

Showmessage('RegOpenKeyEx failed.');

exit;

end;

if RegNotifyChangeKeyValue( hKeyx, //监视子键句柄

TRUE, //监视此项的子键

REG_NOTIFY_CHANGE_NAME or REG_NOTIFY_CHANGE_LAST_SET,

hNotify, //接受注册表变化事件的事件对象句柄

TRUE //注册表变化前报告

) <> ERROR_SUCCESS then

begin

CloseHandle( hNotify );

RegCloseKey( hKeyx );

Showmessage('RegNotifyChangeKeyValue failed');

exit;

end;

dwRes := WaitForSingleObject( hNotify, 60 * 1000 ); //监视一分钟

if dwRes = 0 then

Showmessage( 'Registry will be changed.' );

CloseHandle( hNotify );

RegCloseKey( hKeyx );

end;

要注意的是,API: WaitForSingleObject要等到注册表变化事件发生或者超时才会返回,在此期间我们的程序将失去响应。解决的办法是新建一个线程,在新线程中监视注册表。

对注册表进行扫描要用到另外两个API: RegEnumKey和RegEnumValue。

LONG RegEnumKey(

HKEY hKey, // 要扫描的注册表项目句柄

DWORD dwIndex, // 要扫描的subkey序号

LPTSTR lpName, // 要扫描的subkey名称

LPDWORD lpcbName, // 要扫描的subkey名称占用空间

);

此函数的使用方法是: 首先给dwIndex赋值0, 调用RegEnumKey; 然后Inc(dwIndex), 再调用RegEnumKey,直到返回值为ERROR_NO_MORE_ITEMS,表示没有更多的子项了。

//扫描注册表的例子

//只演示了如何枚举HKEY_CURRENT_USER\Software下的一层子项

procedure TForm1.Button2Click(Sender: TObject);

var

buf : array [0..255] of char;

iRes : integer;

hKeyx : HKEY;

dwIndex, dwSize : DWORD;

begin

if RegOpenKeyEx( HKEY_CURRENT_USER, 'Software', 0, KEY_READ or

KEY_ENUMERATE_SUB_KEYS, hKeyx ) <> ERROR_SUCCESS then

begin

Showmessage('RegOpenKeyEx failed.');

exit;

end;

dwIndex := 0;

repeat

dwSize := 255;

iRes := RegEnumKey( hKeyx, dwIndex, buf, dwSize );

if iRes = ERROR_NO_MORE_ITEMS then

break

else if iRes = ERROR_SUCCESS then

begin

Listbox1.Items.Add( buf );

Inc( dwIndex );

end;

until iRes <> ERROR_SUCCESS;

RegCloseKey( hKeyx );

end;

阅读(1576) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~