当前位置: 首页 > 学习 > 电脑学习 > 程序设计 > Delphi > 编程技巧 > 正文

Delphi实现对注册表的监视和扫描

http://www.zk168.com.cn  招考学习网 2006-4-7 10:08:26
-----------------------------------------------------------[交流]-[打印]-[发送]-[收藏]--
Delphi自带的TRegistry类只能实现注册表的基本操作,如果我们要实时监视注册表的变化或者扫描注册表特定项下的所有子项,TRegistry类就无能为力了。我啃了半天SDK,终于实现了Delphi对注册表的监视与扫描,不敢独享,拿来献给广大的Delphi爱好者。

监视注册表相关项的改变要用到一个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;

-----------------------------------------------------------[交流]-[打印]-[发送]-[收藏]--
最新入库:
 
·实质、过程及意义——阿多尔诺“否定的辩证法”探微
·从Ontology的译名之争看哲学术语的翻译原则
·论马克思主义哲学经典的解释——解释学方法及其在马克
·中国哲学当前的核心与周边问题
·和合学与21世纪文化价值和科技
·中国文化的和合精神与21世纪
·宗教之间理当相互宽容
·上半个世纪的自由主义
·殷周至春秋时期神人关系之演进
·大学之道:构建以“三纲八目”为核心的道德修养体系
相关内容:
 
网友点评:
 
会员名称:
密码:匿名 ·注册·忘记密码?
评论内容:
(最多300个字符)
  查看评论
友情提醒:
 1.库中的资料大都来自互联网、网友上传、各类书籍,在录入的过程中难免会出现错误,恳请网
 友来信指正!
 2.如果网友在本库中未能找到所需要的材料,请登陆到我们的论坛《招考学习网》版块!
 3.考友想加入招考学习网的编辑部,请发信到XueXiWang#Gmail.com(#改为@)附带个人简历
 4.如需转载请注明出处及作者,谢谢合作!
 5.如果您有更好的建议或意见请EMAIL:XueXiWang#Gmail.com (#改为@)
 6.凡标题中有注有“[NO]”字样均不含答案且答案整理中.
 7.如本库中转载文章涉及版权等问题,请相关网站或作者在两周内发邮件通知(EMAIL:  XueXiWang#Gmail.com (#改为@))我们,我们接到通知后立即删除该文章及链接!
你问我答 更多>>