zoukankan      html  css  js  c++  java
  • Delphi实现对注册表的监视和扫描[转]

    声明: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;

  • 相关阅读:
    MacBook下java环境的搭建
    Mac 终端下Homebrew的几个常用命令(新手笔记)
    新手学Appium_Python_Client
    【转】pycharm的一些快捷键
    解决YUM下Loaded plugins: fastestmirror Determining fastest mirrors 的问题
    chrome扩展第三方浏览器下载安装
    php异或加密解密算法的实现
    TortoiseGit客户端密钥配置
    CURL重试发送请求
    关于接收POST请求 $GLOBALS['HTTP_RAW_POST_DATA']
  • 原文地址:https://www.cnblogs.com/railgunman/p/1900694.html
Copyright © 2011-2022 走看看