大家都知道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