.Net中的文件监视功能实现

 

大家都知道Hook的价值,能拦截OS的一些动作,拦截CreateProcess能在进程创建的时候给以判断,比如让这个进程启动不起来,拦截ExitWindowsEx,可以让你的系统关不了机什么的。

 

Hook其实靠的是注入,也没那么神秘,所谓的全局Hook,不过是系统帮你把Hook函数注入到了所有的进程中罢了。那么如果要在C#下监视一个文件夹中,文件有没有被修改,你该怎么办?所谓的“修改”,无非也就是如下4种操作:

+------Add
+------Delete
+------Change
+------Rename

 

C#.Net为我们提供了这么一个实用的功能。看下面的一段Code:

code begin:

using System;
using System.IO;

namespace FileWatcher
{

public class FileWatcherEventArgs : EventArgs
{
   private string mFileName = "";
   private string mPath = "";
   private string mOldPath = "";
   private string mOldName = "";
   private FileWatcher.fileWatcherChangeType mChangeType;

   public FileWatcherEventArgs(string fileName, string path, string oldPath, string oldName, FileWatcher.fileWatcherChangeType changeType)
   {
    mFileName = fileName;
    mPath = path;
    mOldName = oldName;
    mOldPath = oldPath;
    mChangeType = changeType;
   }

省略代码若干...##################

}

public class FileWatcher
{
   #region enums, constants & fields
   public enum fileWatcherChangeType
   {
    fileAdded,
    fileDeleted,
    fileRenamed,
    filechanged
   }

   private string mPath = ".";  
   private string mFilter = "*.*";
   private FileSystemWatcher mFsw = new FileSystemWatcher();
   private string mCurrentFileName = "";
   private string mCurrentPath = "";
   private string mCurrentOldPath = "";
   private string mCurrentOldName = "";
   private fileWatcherChangeType mChangeType;
   #endregion

   #region events and delegates
   public delegate void ChangedEventHandler(object sender, FileWatcherEventArgs args);

   public event ChangedEventHandler Changed;
   #endregion

   #region constructors
   public FileWatcher()
   {
    CreateFileWatcher();
   }

   public FileWatcher(string path, string filter) : this()
   {
    mPath = path;
    mFilter = filter;
   }

   public FileWatcher(string path) : this()
   {
    mPath = path;
   }
   #endregion

   #region Properties

省略代码若干.......#####################

   #endregion

   #region public methods
   public void StartWatcher()
   {
    mFsw.Path = mPath;
    mFsw.Filter = mFilter;
    mFsw.EnableRaisingEvents = true;
   }

   public void StopWatcher()
   {
    mFsw.EnableRaisingEvents = false;
   }

   #endregion

   #region file watcher engine

   private void CreateFileWatcher()
   {
    mFsw = new FileSystemWatcher(mPath,mFilter);
    mFsw.NotifyFilter = NotifyFilters.LastWrite |
     NotifyFilters.DirectoryName | NotifyFilters.FileName;
    mFsw.Changed += new FileSystemEventHandler(OnChanged);
    mFsw.Created += new FileSystemEventHandler(OnCreated);
    mFsw.Deleted += new FileSystemEventHandler(OnDeleted);
    mFsw.Renamed += new RenamedEventHandler(OnRenamed);
   }

   protected virtual void OnChanged(FileWatcherEventArgs e)
   {
   
    Changed(this,e);
   }
   #endregion

   #region private file-change methods
   private void OnCreated(object source, FileSystemEventArgs args)
   {
    mCurrentFileName = args.Name;
    mCurrentPath = args.FullPath;
    mCurrentOldName = "";
    mCurrentOldPath = "";
    mChangeType = fileWatcherChangeType.fileAdded;
    OnChanged(new FileWatcherEventArgs(mCurrentFileName,mCurrentPath,mCurrentOldPath,mCurrentOldName,mChangeType));
   }

   private void OnRenamed(object source, RenamedEventArgs args)
   {
    mCurrentFileName = args.Name;
    mCurrentPath = args.FullPath;
    mCurrentOldName = args.OldFullPath;
    mCurrentOldPath = args.OldName;  
    mChangeType = fileWatcherChangeType.fileRenamed;
    OnChanged(new FileWatcherEventArgs(mCurrentFileName,mCurrentPath,mCurrentOldPath,mCurrentOldName,mChangeType));

   }

   private void OnDeleted(object source, FileSystemEventArgs args)
   {
    mCurrentFileName = args.Name;
    mCurrentPath = args.FullPath;
    mCurrentOldName = "";
    mCurrentOldPath = "";
    mChangeType = fileWatcherChangeType.fileDeleted;
    OnChanged(new FileWatcherEventArgs(mCurrentFileName,mCurrentPath,mCurrentOldPath,mCurrentOldName,mChangeType));
   }

   private void OnChanged(object source, FileSystemEventArgs args)
   {
    mCurrentFileName = args.Name;
    mCurrentPath = args.FullPath;
    mCurrentOldName = "";
    mCurrentOldPath = "";
    mChangeType = fileWatcherChangeType.filechanged;
    OnChanged(new FileWatcherEventArgs(mCurrentFileName,mCurrentPath,mCurrentOldPath,mCurrentOldName,mChangeType));
   }

   #endregion
}
}

 

code end;

上面的代码是C#的一个名称空间,里面引用了FileWatcher这个核心起作用的类。提供了StartWatcher方法和StopWatcher方法,这是2个公有函数,而CreatWatcher则是作为似有函数存在。

private void OnCreated(object source, FileSystemEventArgs args)

private void OnRenamed(object source, RenamedEventArgs args)

private void OnDeleted(object source, FileSystemEventArgs args)

private void OnChanged(object source, FileSystemEventArgs args)

以上四个私有函数则是监视4种动作的状态。

你该怎么使用他呢,把这个FileWatcher.cs拷贝到您的项目中并引用。

编写一个按钮处理事件:

        private void button1_Click(object sender, EventArgs e)
        {
            FileWatcher.FileWatcher fw = new FileWatcher.FileWatcher(@"E:/test");
            fw.StartWatcher();
            fw.Changed += new FileWatcher.FileWatcher.ChangedEventHandler(showChange);

        }
        private void showChange(object source, FileWatcher.FileWatcherEventArgs e)
        {
            MessageBox.Show(e.ChangeType.ToString() + " " + e.FileName);
        }

那么,恭喜你,当你按下这个按钮的时候,这个"E:/test"文件夹中的一举一动都在您的掌握之中了。无论您做这个文件夹做了4样动作中的任意一项,都会提示您操作了什么,操作的文件名又是什么。

 

 

界面上有两个按钮,当按下"StartWatcher"的时候,"Hook"开始了。按下"StopWatcher",就"UnHook"了。

当你向目标文件夹中新建文件的时候:

 

 

删除文件的时候:

 

 

 

 

修改和重命名的截图就不发了,是不是很方便呢?这是一种伪Hook,并不能算是真正意义上的Hook。它的代码由.Net的CLR虚拟机提交给系统托管了,所以实现了类似于Hook的文件监视的功能。

 

 

 

示例源代码下载地址:http://www.brsbox.com/filebox/down/fc/139fc9c189a31ef49444eade84881180

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值