zoukankan      html  css  js  c++  java
  • 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;

  • 相关阅读:
    BlocksKit block从配角到主角—oc通往函数式编程之路--oc rx化?
    使用NSProxy和NSObject设计代理类的差异
    面向发布(部署)编程—热修复、动态库与补丁
    解释器就是虚拟机
    动态和多态的本质是对不确定性的解释机制
    c+多态的本质:编译器维护了类型信息同时插入了解释执行机制
    ios Aspects面向切面沉思录—面向结构编程—面向修改记录编程—面向运行时结构编程—元编程?
    知行合一的方法论
    面向运行时结构信息编程
    c++、oc、swift初步评价
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/3668941.html
Copyright © 2011-2022 走看看