VB.NET中監(jiān)視文件夾的變化 Montaque(原作)
發(fā)表時間:2023-08-16 來源:明輝站整理相關軟件相關文章人氣:
[摘要]VB.NET中監(jiān)視文件夾的變化Montaque(原作)摘要 : 有時候,處于業(yè)務的需要,我們要不斷的監(jiān)視文件的變化,比如文件的創(chuàng)建、刪除、重命名等;而且某些人要確保重要文件的只讀,并且要及時的報告文...
VB.NET中監(jiān)視文件夾的變化Montaque(原作)
摘要 :
有時候,處于業(yè)務的需要,我們要不斷的監(jiān)視文件的變化,比如文件的創(chuàng)建、刪除、重命名等;而且某些人要確保重要文件的只讀,并且要及時的報告文件版本的變更情況;蛘,你想監(jiān)視你的文件夾被別人更改、肆意刪除而又不知道是誰干的,在什么時候干的?于是你就考慮要寫一個監(jiān)視程序,“偷偷的”記錄文件夾被操作的情況。
有些人采取常規(guī)的方式,即寫一個桌面應用程序,其界面可能是隱藏的。采用每隔一個事件片段讀取文件信息,然后寫到一個log文件中。然后設置系統(tǒng)啟動的事件自動加載程序,(好像很多人是這樣竊取QQ密碼的:()。其缺點:1、不是連續(xù)的獲取信息,因為他們采用了Timer的tick事件;2、在NT系統(tǒng)中,可能要一定的權限才可以運行,比如要管理員身份等。還有系統(tǒng)中會有進程顯示,顯然很容易shutdown.
我們建議的方案:采用.NET的Windows Service。首先可以克服以上缺點,而且較VB6的編程而言,.NET中寫windows service一如反掌。
思路:
在.NET創(chuàng)建的服務中調(diào)用System.IO.FileSystemWatcher對象,每次被監(jiān)視的文件或者文件夾變化的時候,調(diào)用IO系統(tǒng)的FileStream和StreamWriter把變更信息寫到log文件中。
正文:
關于.NET中的Windows服務:
Windows服務,是一些長久運行的程序,而并不需要依靠登錄用戶或客戶程序來保持它的運行。它們沒有自己的用戶界面,可以在它們自己獨有的安全級別和會話上下文中運行。我們比較熟悉的Windows服務范例包含了從打印池到SQL服務器以及它的分布式事務協(xié)作(DTC)。服務只可以運行在NT、2000以及后繼產(chǎn)品比如XP下運行,它們通過Microsoft Management Console (MMC)提供了一個專門的管理界面(開始->運行->Services.msc)。
在.NET中創(chuàng)建項目的時候,有一個Windows服務的模板,選擇新建。這個操作自動為我建立了一個新的類,它是繼承了.NET內(nèi)建了System.ServiceProcess.ServiceBase類。同時它提供給我一個可視化的設計器,一個圖形化的快速開發(fā)工具,它特別的為那些本身沒有用戶界面的工程。我可以點擊這個設計器,設定我的服務的名字(我命名為"File Watching")。
當啟動某項服務時,系統(tǒng)將定位相應的可執(zhí)行文件,并運行該服務的 OnStart 方法(它包含在可執(zhí)行文件內(nèi))。但是,運行服務與運行可執(zhí)行文件并不相同。可執(zhí)行文件僅加載服務。服務則通過“服務控制管理器”訪問(例如啟動和停止)。
當首次在服務上調(diào)用“開始”時,可執(zhí)行文件將調(diào)用 ServiceBase 派生類的構造函數(shù)。在構造函數(shù)執(zhí)行之后將立即調(diào)用 OnStart 命令處理方法。在服務首次加載之后,構造函數(shù)不會再次執(zhí)行,因此有必要將構造函數(shù)執(zhí)行的處理和 OnStart 執(zhí)行的處理分開?梢杂 OnStop 釋放的任何資源都應在 OnStart 中創(chuàng)建。如果服務在 OnStop 釋放資源后再次啟動,那么,在構造函數(shù)中創(chuàng)建資源會妨礙這些資源的正確創(chuàng)建。
“服務控制管理器”(SCM) 提供與服務交互的方式?梢允褂 SCM 將“開始”(Start)、“停止”(Stop)、“暫!(Pause)、“繼續(xù)”(Continue) 或自定義命令傳遞到服務中。SCM 使用 CanStop 和 CanPauseAndContinue 的值,決定服務是否接受“停止”、“暫!被颉袄^續(xù)”命令。僅當服務類中相應的屬性 CanStop 或 CanPauseAndContinue 為 true 時,才會在 SCM 的上下文菜單中啟用“停止”、“暫!被颉袄^續(xù)”。如果已啟用,則相應的命令將傳遞到服務,并且調(diào)用 OnStop、OnPause 或 OnContinue。如果 CanStop、CanShutdown 或 CanPauseAndContinue 為 false,則即使已實現(xiàn)相應的命令處理方法(如 OnStop),也不會予以處理。
上面是創(chuàng)建任何一個服務,我們都會涉及到的只是,具體在監(jiān)視文件夾變化的時候,我們用到了FileSystemWatcher。
關于FileSystemWatcher:
偵聽文件系統(tǒng)更改通知,并在目錄或目錄中的文件發(fā)生更改時引發(fā)事件。
使用 FileSystemWatcher 監(jiān)視指定目錄中的更改?杀O(jiān)視指定目錄中的文件或子目錄的更改。該組件可以監(jiān)視本地計算機、網(wǎng)絡驅動器或遠程計算機上的文件。(當然只讀的媒體介質(zhì)比如cd和dvd,它們文件的屬性不會改變,所以也就不能觸發(fā)事件)
若要監(jiān)視所有文件中的更改,請將 Filter 屬性設置為空字符串 ("")。若要監(jiān)視特定的文件,請將 Filter 屬性設置為該文件名。例如,若要監(jiān)視文件 MyDoc.txt 中的更改,請將 Filter 屬性設置為“MyDoc.txt”。也可以監(jiān)視特定類型文件中的更改。例如,若要監(jiān)視文本文件中的更改,請將 Filter 屬性設置為“*.txt”。
可監(jiān)視目錄或文件中的若干種更改。例如,可監(jiān)視文件或目錄的 Attributes、LastWrite 日期和時間或 Size 方面的更改。通過將 FileSystemWatcher.NotifyFilter 屬性設置為 NotifyFilters 值之一來達到此目的。
可監(jiān)視文件或目錄的重命名、刪除或創(chuàng)建。例如,若要監(jiān)視文本文件的重命名,請將 Filter 屬性設置為“*.txt”,并調(diào)用 WaitForChanged 方法之一,調(diào)用時給出 WatcherChangeTypes 值的 Renamed。
Demo:
新建一個project,選擇windows 服務類型,命名為WinServiceFileWatching,我們看到project的引用中自動添加了System.ServiceProcess名空間(這就是創(chuàng)建一個服務的函數(shù)集)。從工具中的組件中選擇FileSystemWatcher1,拖放到service1的設計模式上,然后設置如下屬性:
Filter 獲取或設置篩選字符串,用于確定在目錄中監(jiān)視哪些文件。 我們設置為*.*,即所有文件
IncludeSubdirectories 獲取或設置一個值,該值指示是否監(jiān)視指定路徑中的子目錄。 設置為true
Path 獲取或設置要監(jiān)視的目錄的路徑 設置為我們要監(jiān)視的對象,比如C:\DonnetData
然后添加以下代碼:
Protected Overrides Sub OnStart(ByVal args() As String)
' 在此處添加啟動服務的代碼。此方法應設置具體的操作
' 以便服務可以執(zhí)行它的工作。
FileSystemWatcher1.EnableRaisingEvents = True
' 我們也可以根據(jù)輸入的參數(shù)args動態(tài)設定要監(jiān)視的對象
'FileSystemWatcher1.path= args(0)
End Sub
' 創(chuàng)建文件(夾)時候觸發(fā),記錄創(chuàng)建信息到e:\log.txt中
Private Sub FileSystemWatcher1_Created(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Created
Dim fs As New FileStream("e:\log.txt", FileMode.Append)
Dim sw As New StreamWriter(fs)
sw.WriteLine(Now() & Microsoft.VisualBasic.vbTab & "創(chuàng)建" & e.FullPath)
sw.Close()
fs.Close()
End Sub
' Rename文件(夾)時候觸發(fā),記錄創(chuàng)建信息到e:\log.txt中
Private Sub FileSystemWatcher1_Renamed(ByVal sender As Object, ByVal e As System.IO.RenamedEventArgs) Handles FileSystemWatcher1.Renamed
Dim fs As New FileStream("e:\log.txt", FileMode.Append)
Dim sw As New StreamWriter(fs)
sw.WriteLine(Now() & Microsoft.VisualBasic.vbTab & "重命名" & e.OldFullPath & "-" & e.FullPath)
sw.Close()
fs.Close()
End Sub
' 刪除文件(夾)時候觸發(fā),記錄創(chuàng)建信息到e:\log.txt中
Private Sub FileSystemWatcher1_Deleted(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Deleted
Dim fs As New FileStream("e:\log.txt", FileMode.Append)
Dim sw As New StreamWriter(fs)
sw.WriteLine(Now() & Microsoft.VisualBasic.vbTab & "刪除" & e.FullPath)
sw.Close()
fs.Close()
End Sub
到目前為止,這個服務已經(jīng)寫好了,下面作一個安裝程序:
在service的設計模式上點擊右鍵,選擇添加安裝程序。系統(tǒng)會自動添加一個類ProjectInstaller,設計模式上有一個ServiceProcessInstaller1 和ServiceInstaller1。設置ServiceInstaller1的Display Name為File Watching Service,starttype為Automatic,表示自動啟動。設置ServiceProcessInstaller1 的account為LocalSystem。
由于服務是不能運行的,我們選擇生成解決方案。ok!
最后安裝我們的服務:
.NET Framework自帶了一個工具,InstallUtil,使用很簡單InstallUtil c:\winservicefilewatching\bin\winservicefilewatching.exe ' 剛才編譯好的程序的路徑
這樣就安裝好了,Uninstall也很容易。首先SCM中關閉服務,InstallUtil/u c:\...\winservicefilewatching.exe 'the same path
這樣在系統(tǒng)的services中就會多出一個服務,顯示為File Watching Service,選擇啟動就可以開始監(jiān)視...
總結:
在.NET創(chuàng)建的服務中調(diào)用System.IO.FileSystemWatcher對象,每次被監(jiān)視的文件或者文件夾變化的時候,調(diào)用IO系統(tǒng)的FileStream和StreamWriter把變更信息寫到log文件中。實際上利用了.NET強大的內(nèi)置集成功能,把復雜的文件簡單話。