有时候
处于业务的需要
我们要不断的监视文件的变化
比如文件的创建
删除
重命名等
而且某些人要确保重要文件的只读
并且要及时的报告文件版本的变更情况
或者
你想监视你的文件夹被别人更改
肆意删除而又不知道是谁干的
在什么时候干的?于是你就考虑要写一个监视程序
偷偷的
记录文件夹被操作的情况
有些人采取常规的方式即写一个桌面应用程序其界面可能是隐藏的采用每隔一个事件片段读取文件信息然后写到一个log文件中然后设置系统启动的事件自动加载程序(好像很多人是这样窃取QQ密码的)其缺点不是连续的获取信息因为他们采用了Timer的tick事件在NT系统中可能要一定的权限才可以运行比如要管理员身份等还有系统中会有进程显示显然很容易shutdown
我们建议的方案采用NET的Windows Service首先可以克服以上缺点而且较VB的编程而言NET中写windows service一如反掌
思路在NET创建的服务中调用SystemIOFileSystemWatcher对象每次被监视的文件或者文件夹变化的时候调用IO系统的FileStream和StreamWriter把变更信息写到log文件中
关于NET中的Windows服务
Windows服务是一些长久运行的程序而并不需要依靠登录用户或客户程序来保持它的运行它们没有自己的用户界面可以在它们自己独有的安全级别和会话上下文中运行我们比较熟悉的Windows服务范例包含了从打印池到SQL服务器以及它的分布式事务协作(DTC)服务只可以运行在NT以及后继产品比如XP下运行它们通过Microsoft Management Console (MMC)提供了一个专门的管理界面(开始->运行>Servicesmsc)
在NET中创建项目的时候有一个Windows服务的模板选择新建这个操作自动为我建立了一个新的类它是继承了NET内建了SystemServiceProcessServiceBase类同时它提供给我一个可视化的设计器一个图形化的快速开发工具它特别的为那些本身没有用户界面的工程我可以点击这个设计器设定我的服务的名字(我命名为File Watching)
当启动某项服务时系统将定位相应的可执行文件并运行该服务的 OnStart 方法(它包含在可执行文件内)但是运行服务与运行可执行文件并不相同可执行文件仅加载服务服务则通过服务控制管理器访问(例如启动和停止)
当首次在服务上调用开始时可执行文件将调用 ServiceBase 派生类的构造函数在构造函数执行之后将立即调用 OnStart 命令处理方法在服务首次加载之后构造函数不会再次执行因此有必要将构造函数执行的处理和 OnStart 执行的处理分开可以由 OnStop 释放的任何资源都应在 OnStart 中创建如果服务在 OnStop 释放资源后再次启动那么在构造函数中创建资源会妨碍这些资源的正确创建
服务控制管理器(SCM) 提供与服务交互的方式可以使用 SCM 将开始(Start)停止(Stop)暂停(Pause)继续(Continue) 或自定义命令传递到服务中SCM 使用 CanStop 和 CanPauseAndContinue 的值决定服务是否接受停止暂停或继续命令仅当服务类中相应的属性 CanStop 或 CanPauseAndContinue 为 true 时才会在 SCM 的上下文菜单中启用停止暂停或继续如果已启用则相应的命令将传递到服务并且调用 OnStopOnPause 或 OnContinue如果 CanStopCanShutdown 或 CanPauseAndContinue 为 false则即使已实现相应的命令处理方法(如 OnStop)也不会予以处理
上面是创建任何一个服务我们都会涉及到的只是具体在监视文件夹变化的时候我们用到了FileSystemWatcher
关于FileSystemWatcher
侦听文件系统更改通知并在目录或目录中的文件发生更改时引发事件
使用 FileSystemWatcher 监视指定目录中的更改可监视指定目录中的文件或子目录的更改该组件可以监视本地计算机网络驱动器或远程计算机上的文件(当然只读的媒体介质比如cd和dvd它们文件的属性不会改变所以也就不能触发事件)
若要监视所有文件中的更改请将 Filter 属性设置为空字符串 ()若要监视特定的文件请将 Filter 属性设置为该文件名例如若要监视文件 MyDoctxt 中的更改请将 Filter 属性设置为MyDoctxt也可以监视特定类型文件中的更改例如若要监视文本文件中的更改请将 Filter 属性设置为*txt
可监视目录或文件中的若干种更改例如可监视文件或目录的 AttributesLastWrite 日期和时间或 Size 方面的更改通过将 FileSystemWatcherNotifyFilter 属性设置为 NotifyFilters 值之一来达到此目的
可监视文件或目录的重命名删除或创建例如若要监视文本文件的重命名请将 Filter 属性设置为*txt并调用 WaitForChanged 方法之一调用时给出 WatcherChangeTypes 值的 Renamed
Demo
新建一个project选择windows 服务类型命名为WinServiceFileWatching我们看到project的引用中自动添加了SystemServiceProcess名空间(这就是创建一个服务的函数集)从工具中的组件中选择FileSystemWatcher拖放到service的设计模式上然后设置如下属性
Filter 获取或设置筛选字符串
用于确定在目录中监视哪些文件
我们设置为*
*
即所有文件IncludeSubdirectories获取或设置一个值
该值指示是否监视指定路径中的子目录
设置为truePath获取或设置要监视的目录的路径 设置为我们要监视的对象
比如C:\DonnetData
然后添加以下代码
Protected Overrides Sub OnStart(ByVal args() As String)
在此处添加启动服务的代码此方法应设置具体的操作
以便服务可以执行它的工作
FileSystemWatcherEnableRaisingEvents = True
我们也可以根据输入的参数args动态设定要监视的对象
FileSystemWatcherpath= args()
End Sub
创建文件(夹)时候触发记录创建信息到e:\logtxt中
Private Sub FileSystemWatcher_Created(ByVal sender As Object ByVal e As SystemIOFileSystemEventArgs) Handles FileSystemWatcherCreated
Dim fs As New FileStream(e:\logtxt FileModeAppend)
Dim sw As New StreamWriter(fs)
swWriteLine(Now() & MicrosoftVisualBasicvbTab & 创建 & eFullPath)
swClose()
fsClose()
End Sub
Rename文件(夹)时候触发记录创建信息到e:\logtxt中
Private Sub FileSystemWatcher_Renamed(ByVal sender As Object ByVal e As SystemIORenamedEventArgs) Handles FileSystemWatcherRenamed
Dim fs As New FileStream(e:\logtxt FileModeAppend)
Dim sw As New StreamWriter(fs)
swWriteLine(Now() & MicrosoftVisualBasicvbTab & 重命名 & eOldFullPath & & eFullPath)
swClose()
fsClose()
End Sub
删除文件(夹)时候触发记录创建信息到e:\logtxt中
Private Sub FileSystemWatcher_Deleted(ByVal sender As Object ByVal e As SystemIOFileSystemEventArgs) Handles FileSystemWatcherDeleted
Dim fs As New FileStream(e:\logtxt FileModeAppend)
Dim sw As New StreamWriter(fs)
swWriteLine(Now() & MicrosoftVisualBasicvbTab & 删除 & eFullPath)
swClose()
fsClose()
End Sub
到目前为止这个服务已经写好了下面作一个安装程序
在service的设计模式上点击右键选择添加安装程序系统会自动添加一个类ProjectInstaller设计模式上有一个ServiceProcessInstaller 和ServiceInstaller设置ServiceInstaller的Display Name为File Watching Servicestarttype为Automatic表示自动启动设置ServiceProcessInstaller 的account为LocalSystem
由于服务是不能运行的我们选择生成解决方案ok!
最后安装我们的服务
NET Framework自带了一个工具InstallUtil使用很简单InstallUtil c:\winservicefilewatching\bin\winservicefilewatchingexe 刚才编译好的程序的路径这样就安装好了Uninstall也很容易首先SCM中关闭服务InstallUtil/u c:\\winservicefilewatchingexe the same path
这样在系统的services中就会多出一个服务显示为File Watching Service选择启动就可以开始监视
总结
在NET创建的服务中调用SystemIOFileSystemWatcher对象每次被监视的文件或者文件夹变化的时候调用IO系统的FileStream和StreamWriter把变更信息写到log文件中实际上利用了NET强大的内置集成功能把复杂的文件简单话