WEB开发网
开发学院软件开发Delphi Delphi实现对注册表的监视和扫描 阅读

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

 2006-02-04 13:45:52 来源:WEB开发网   
核心提示:声明:CSDN以外的任合团体和个人转载本文必须注明出处和作者, Delphi自带的TRegistry类只能实现注册表的基本操作,Delphi实现对注册表的监视和扫描,如果我们要实时监视注册表的变化或者扫描注册表特定项下的所有子项,TRegistry类就无能为力了, LONG RegEnumKey( HKEY hK

声明:CSDN以外的任合团体和个人转载本文必须注明出处和作者。

   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;

Tags:Delphi 实现 注册表

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接