監視程序,這個名字聽起來似乎很陌生。它的用途主要是在後台監視系統中關鍵信息的改變,比如注冊表的改變及硬盤上由於文件操作引起的改變等等。
也許有人會問了,編制這樣的程序有什麼價值呢?硬盤上文件改變了,我只要在資源管理器裡點一點不就全都清楚了嗎?問題當然不會這樣簡單,如今大家的硬盤都已經用G來做單位了,一塊4.3G的硬盤中,大大小小的文件全都加起來也會有若干萬(相信新購機的朋友會考慮IBM10.1G的大硬盤,那文件數量將更加不可想象),更何況那些看不見的系統文件和隱藏文件了。再加上注冊表,那其中的條條款款,數量也絲毫不遜於硬盤上的文件。要想隨時知道自己機器是否有所變動,絕對不是一件很輕松的事。而監視程序就可以隨時檢測到這些變化,幫助我們了解這些情況。
當然這只是監視程序的一部分作用,它最大的作用就是可以記錄下某個軟件安裝前後系統的改變,從而為卸載這個軟件提供重要的依據。雖然Windows自帶了一個Uninstall Shield,但是它似乎並不能很干淨地把原來的軟件卸掉,每次卸載總會留下一些討厭的殘渣,致使系統中的垃圾信息不斷增長,我們的硬盤空間也總是莫名其妙地越用越少。因此,一些號稱能夠完全卸載軟件的專用卸載工具應運而生。在這其中,有一些就運用了監視系統的技術,比如Uninstaller Manager和RegMonitor。
下面我們開始討論如何編程實現這一監視功能。首先介紹幾個重要的api函數:
FindFirstChangeNotification( );
FindNextChangeNotification( );
WaitForSingleObject( );
其中FindFirstChangeNotification(lpzpath,fwatchsubtree,fdwfilter)中的lpzpath表示要監視的路徑名,fwatchsubtree判斷是否查看子目錄,fdwfilter為要監視的事件,函數執行成功後返回一個句柄。
參數fdwfilter取值及其含義如下:
FILE_NOTIFY_CHANGE_FILE_NAME 查看指定目錄下任何文件名的改變
FILE_NOTIFY_CHANGE_DIR_NAME 查看指定目錄下任何目錄名的改變
FILE_NOTIFY_CHANGE_SIZE 查看指定目錄下文件大小的改變
FILE_NOTIFY_CHANGE_ATTRIBUTES 查看指定目錄下文件屬性的改變
FindNextChangeNotification(hchange),hchange為FindFirstChangenNotification返回的句柄,其作用是請求系統
在下次檢測到相應改變時發出改變通知消息句柄。當函數成功返回後,應用程序可通過WaitForMultipleObjects或WaitfForSingleObject來等待發生改變的通知。WaitForSingleObject(hchange,dwmilliseconds)中hchange為FindFirstChangeNotification 返回的句柄,dwmilliseconds為等待時間值,指定等待完成需要的時間,單位為毫秒。該值為-1時表示時間無限長。最好在結束監視程序之前先用FindCloseChangeNotification(hchange)來關閉句柄。
下面給出一個簡單的實例,其功能就是監視c:\pwin98目錄下是否有文件發生變化。一旦有重命名、創建或刪除情況發生時,通過Edit控件給出提示。
//
----------------
#include
#pragma hdrstop
#include “Unit1.h”
//----------------
#pragma package(smart_init)
#pragma resource “*.dfm”
TForm1 *Form1;
//-----------------
__fastcall TForm1::TForm1(Tcomponent* Owner)
: Tform(Owner)
{
}
//-------------------
void __fastcall TForm1::FormCreate(Tobject *Sender)
{
DWORD dwWaitStatus;
HANDLE dwChangeHandle; //返回通知的句柄
dwChangeHandle=FindFirstChangeNotification(
“C:\\PWIN98”,false,FILE_NOTIFY_CHANGE_FILE_NAME); //設置返回通知的句柄
if(dwChangeHandle==INVALID_HANDLE_VALUE)
//判斷是否設置成功
ExitProcess(GetLastError( ));
while(true){ //設置循環,監視是否有
dwWaitStatus=WaitForSingleObject(dwChangeHandle,-1); //通知返回
switch(dwWaitStatus){
case 0:
Edit1->Text=“Something Changed”; //給出提示
FindCloseChangeNotification(dwcChangeHandle); //關閉句柄
exit(EXIT_SUCCESS); //退出程序
default:
ExitProcess(GetLastError( ));
}
}
}
程序在C++Builder4/PWin98下通過,由於C++Builder語言很標准,所以很容易擴展到其他編程語言環境中去。
此例說明如何監視硬盤中文件變化,對於注冊表,則有函數RegNotifyChangeKeyValue( )可以實現類似功能,這裡暫省略之。
怎麼樣,看過本文,是否對Uninstaller Manager和Reg Monitor這樣的軟件有了更深入的了解。在Windows編程中,有些API函數起到了重要的作用,可以讓程序實現很多高級的功能。因為API函數是按照C語言語法給出的,所以C++Builder有著得天獨厚的優勢,對API函數和宏支持得非常好。不好,怎麼跑題了?
還愣著干嗎,難道你還不想趕快動手編制一個自己的Uninstaller Manager嗎?