科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道应用软件Delphi实现对注册表的监视和扫描

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

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

Delphi自带的TRegistry类只能实现注册表的基本操作,本文讲解如何让Delphi实现对注册表的监视和扫描

作者:51cto.com整理 来源:51cto.com整理 2007年9月15日

关键字: Delphi 监视 扫描 软件

  • 评论
  • 分享微博
  • 分享邮件

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;

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章