监视程序的编制 (哈尔滨 赵晓辉) 监视程序，这个名字听起来似乎很陌生。它的用途主要是在后台监视系统中关键信息的改变，比如注册表 的改变及硬盘上由于文件操作引起的改变等等。也许有人会问了，编制这样的程序有什么价值呢？硬盘上文件 改变了，我只要在资源管理器里点一点不就全都清楚了吗？问题当然不会这样简单，如今大家的硬盘都已经用 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），hchan ge为FindFirstChangenNotification返回的句柄，其作用是请求系统在下次检测到相应改变时发出改变通 知消息句柄。当函数成功返回后，应用程序可通过WaitForMultipleObjects或WaitfForSingleObject来等待发 生改变的通知。WaitForSingleObject（hchange，dwmilliseconds）中hchange为FindFirstChangeNotificati on　返回的句柄，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这样的软件有了更深入的了解。在Wind ows编程中，有些API函数起到了重要的作用，可以让程序实现很多高级的功能。因为API函数是按照C语言语法 给出的，所以C＋＋Builder有着得天独厚的优势，对API函数和宏支持得非常好。不好，怎么跑题了？ 还愣着干吗，难道你还不想赶快动手编制一个自己的Uninstaller Manager吗？