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


    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_USERSoftware项下所有子键
    procedure TForm1.Button1Click(SenderTObject);
    var
    hNotify THandle;
    hKeyx HKEY;
    dwRes DWORD;
    begin
    hNotify := CreateEventnil//不使用SECURITY_ATTRIBUTES结构
    FALSE//不自动重置
    TRUE//设置初始状态
    'RegistryNotify' //事件对象的名称
    );

    if hNotify 0 then
    begin
    Showmessage('CreateEvent failed.');
    exit;
    end;

    if RegOpenKeyExHKEY_CURRENT_USER//跟键
    'Software'//子键
    0//reserved
    KEY_NOTIFY//监视用
    hKeyx //保存句柄
    ) <> ERROR_SUCCESS then
    begin
    CloseHandlehNotify );
    Showmessage('RegOpenKeyEx failed.');
    exit;
    end;

    if RegNotifyChangeKeyValuehKeyx//监视子键句柄
    TRUE//监视此项的子键
    REG_NOTIFY_CHANGE_NAME or REG_NOTIFY_CHANGE_LAST_SET,
    hNotify//接受注册表变化事件的事件对象句柄
    TRUE //注册表变化前报告
    ) <> ERROR_SUCCESS then
    begin
    CloseHandlehNotify );
    RegCloseKeyhKeyx );
    Showmessage('RegNotifyChangeKeyValue failed');
    exit;
    end;

    dwRes := WaitForSingleObjecthNotify60 1000 ); //监视一分钟
    if dwRes 0 then
    Showmessage'Registry will be changed.' );

    CloseHandlehNotify );
    RegCloseKeyhKeyx );
    end;


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

    对注册表进行扫描要用到另外两个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_USERSoftware下的一层子项
    procedure TForm1.Button2Click(SenderTObject);
    var
    buf array [0..255of char;
    iRes integer;
    hKeyx HKEY;
    dwIndexdwSize DWORD;
    begin
    if 
    RegOpenKeyExHKEY_CURRENT_USER'Software'0KEY_READ or
    KEY_ENUMERATE_SUB_KEYShKeyx ) <> ERROR_SUCCESS then
    begin
    Showmessage('RegOpenKeyEx failed.');
    exit;
    end;

    dwIndex := 0;
    repeat
    dwSize := 255;
    iRes := RegEnumKeyhKeyxdwIndexbufdwSize );
    if iRes ERROR_NO_MORE_ITEMS then
    break
    else if iRes ERROR_SUCCESS then
    begin
    Listbox1.Items.Addbuf );
    IncdwIndex );
    end;
    until iRes <> ERROR_SUCCESS;

    RegCloseKeyhKeyx );
    end;

  • 相关阅读:
    (转)mysql 中的 latch锁和Tlock(事务锁), DML加锁规则,以及死锁分析
    改变主库sync_binlog,减小主从同步延时
    windows10上使用SourceInsight阅读mysql源码
    centos6.5安装systemstap
    centos6.5编译调试mysql-5.7.18
    事物特性
    Union和union all区别?
    Join(inner、left、right)的区别?
    hashhashmaphashTablehashSet
    String、StringBuffer、StringBuilder区别
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/3668941.html
Copyright © 2020-2023  润新知