监视程序的编制

整理日:2015/3/25

监视程序, 这个名字听起来似乎很陌生. 它的用途主要是在后台监视系统中关键信息的改变, 比如注册表的改变及硬盘上由于文件操作引起的改变等等.

也许有人会问了, 编制这样的程序有什么价值呢? 硬盘上文件改变了, 我只要在资源管理器里点一点不就全都清楚了吗? 问题当然不会这样简单, 如今大家的硬盘都已经用G来做单位了, 一块4.3G的硬盘中, 大大小小的文件全都加起来也会有若干万(相信新购机的朋友会考虑IBM10.1G的大硬盘, 那文件数量将更加不可想象), 更何况那些看不见的系统文件和隐藏文件了. 再加上注册表, 那其中的条条款款, 数量也丝毫不逊于硬盘上的文件. 要想随时知道自己机器是否有所变动, 绝对不是一件很轻松的事. 而监视程序就可以随时检测到这些变化, 帮助我们了解这些情况.

当然这只是监视程序的一部分作用, 它最大的作用就是可以记录下某个软件安装前后系统的改变, 从而为卸载这个软件提供重要的依据. 虽然Windows自带了一个Uninstall Shield, 但是它似乎并不能很干净地把原来的软件卸掉, 每次卸载总会留下一些讨厌的残渣, 致使系统中的垃圾信息不断增长, 我们的硬盘空间也总是莫名其妙地越用越少. 因此, 一些号称能够完全卸载软件的专用卸载工具应运而生. 在这其中, 有一些就运用了监视系统的技术, 比如Uninstaller Manager和RegMonitor.

下面我们开始讨论如何编程实现这一监视功能. 首先介绍几个重要的api函数:

FindFirstChangeNotification();
FindNextChangeNotification();
WaitForSingleObject();
FindCloseChangeNotification();

FindFirstChangeNotification
其中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
FindNextChangeNotification(hchange), hchange为FindFirstChangenNotification返回的句柄, 其作用是请求系统在下次检测到相应改变时发出改变通知消息句柄. 当函数成功返回后, 应用程序可通过WaitForMultipleObjects或WaitfForSingleObject来等待发生改变的通知.

WaitForSingleObject
WaitForSingleObject(hchange, dwmilliseconds)中hchange为FindFirstChangeNotification 返回的句柄, dwmilliseconds为等待时间值, 指定等待完成需要的时间, 单位为毫秒. 该值为-1时表示时间无限长.

FindCloseChangeNotification
最好在结束监视程序之前先用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吗?

原文链接: https://www.cnblogs.com/wanglinqiang/p/4364662.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    监视程序的编制

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/171333

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 上午2:14
下一篇 2023年2月12日 上午2:20

相关推荐