Delphi實(shí)現(xiàn)對(duì)注冊(cè)表的監(jiān)視和掃描

字號(hào):

Delphi自帶的TRegistry類只能實(shí)現(xiàn)注冊(cè)表的基本操作,如果我們要實(shí)時(shí)監(jiān)視注冊(cè)表的變化或者掃描注冊(cè)表特定項(xiàng)下的所有子項(xiàng),TRegistry類就無(wú)能為力了。我啃了半天SDK,終于實(shí)現(xiàn)了Delphi對(duì)注冊(cè)表的監(jiān)視與掃描,不敢獨(dú)享,拿來(lái)獻(xiàn)給廣大的Delphi愛好者。
    監(jiān)視注冊(cè)表相關(guān)項(xiàng)的改變要用到一個(gè)API:RegNotifyChangeKeyValue。
    LONG RegNotifyChangeKeyValue(
    HKEY hKey, // 要監(jiān)視的一個(gè)項(xiàng)的句柄
    BOOL bWatchSubtree, // 是否監(jiān)視此項(xiàng)的子鍵
    DWORD dwNotifyFilter, // 監(jiān)視哪些變化
    HANDLE hEvent, // 接受注冊(cè)表變化事件的事件對(duì)象句柄
    BOOL fAsynchronous// 注冊(cè)表變化前報(bào)告還是注冊(cè)表變化后才報(bào)告
    );
    注意上面的hEvent是接受注冊(cè)表變化事件的事件對(duì)象句柄,我們要用API:CreateEvent來(lái)創(chuàng)建一個(gè)系統(tǒng)事件對(duì)象。
    HANDLE CreateEvent(
    LPSECURITY_ATTRIBUTES lpEventAttributes, // SECURITY_ATTRIBUTES結(jié)構(gòu)
    BOOL bManualReset, // 是否自動(dòng)重置
    BOOL bInitialState, // 是否設(shè)置初始狀態(tài)
    LPCTSTR lpName// 事件對(duì)象的名稱
    );
    新建一個(gè)工程,添加一個(gè)ListBox,兩個(gè)Button。
    //先寫個(gè)監(jiān)視注冊(cè)表的例子
    //監(jiān)視HKEY_CURRENT_USER\\Software項(xiàng)下所有子鍵
    procedure TForm1.Button1Click(Sender: TObject);
    var
    hNotify : THandle;
    hKeyx : HKEY;
    dwRes : DWORD;
    begin
    hNotify := CreateEvent( nil, //不使用SECURITY_ATTRIBUTES結(jié)構(gòu)
    FALSE, //不自動(dòng)重置
    TRUE,//設(shè)置初始狀態(tài)
    \’RegistryNotify\’ //事件對(duì)象的名稱
    );
    if hNotify = 0 then
    begin
    Showmessage(\’CreateEvent failed.\’);
    exit;
    end;
    if RegOpenKeyEx( HKEY_CURRENT_USER, //跟鍵
    \’Software\’, //子鍵
    0, //reserved
    KEY_NOTIFY, //監(jiān)視用
    hKeyx //保存句柄
    ) <> ERROR_SUCCESS then
    begin
    CloseHandle( hNotify );
    Showmessage(\’RegOpenKeyEx failed.\’);
    exit;
    end;
    if RegNotifyChangeKeyValue( hKeyx, //監(jiān)視子鍵句柄
    TRUE, //監(jiān)視此項(xiàng)的子鍵
    REG_NOTIFY_CHANGE_NAME or REG_NOTIFY_CHANGE_LAST_SET,
    hNotify, //接受注冊(cè)表變化事件的事件對(duì)象句柄
    TRUE //注冊(cè)表變化前報(bào)告
    ) <> ERROR_SUCCESS then