SDK路报--"VC之路"杂志 No.1


监视程序的编制

(哈尔滨 赵晓辉)

 

   


监视程序,这个名字听起来似乎很陌生。它的用途主要是在后台监视系
统中关键信息的改变,比如注册表的改变及硬盘上由于文件操作引起的改变
等等。
也许有人会问了,编制这样的程序有什么价值呢?硬盘上文件改变了,
我只要在资源管理器里点一点不就全都清楚了吗?问题当然不会这样简单,
如今大家的硬盘都已经用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为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吗?

 

 


CopyRight by VCROAD ©2000-2001 All Right Reserve