ホントに便利っすよねーこれ。
一回だけ使った事あった、かな...?
普通に使うと非同期でファイル監視をしてくれます。
WaitForChanged を使うと、同期でファイル監視を行います。(つまり、WaitForChanged がすぐに実行される。)
でも何故か同期の通信が私の環境ではうまくいかず、常にタイムアウトしてしまいました。
なんでだろ... noteWatcher.Path プロパティを WATCH_PATH にしてもうまくいかず、
ためしに FileSystemWatcher1.Path に REMOTE_PATH を設定してみたらうまくいったんすよ。
だから、ローカルとかリモートとかは関係ないんじゃないかなぁと。
なにが間違ってんのかな~。
■参考文献
ファイル システム イベントへの応答
FileSystemWatcher クラス
NotifyFilters 列挙体
FileSystemEventArgs クラス
ErrorEventArgs クラス
RenamedEventArgs クラス
WatcherChangeTypes 列挙体
■実行画像
実行したところ
Public Class FileSystemWatcherTest
Private Const WATCH_PATH As String = "D:\わんくま"
Private Const REMOTE_PATH As String = "\\naoko_note\わんくま"
Private Sub FileSystemWatcherTest_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.ListBox1.Items.Clear()
With Me.FileSystemWatcher1
.BeginInit()
.Path = WATCH_PATH
.Filter = "" ' すべてを監視する
.IncludeSubdirectories = True ' サブディレクトリも監視
' バッファサイズを指定する。適切なバッファサイズに関しては、以下参照
' http://msdn2.microsoft.com/ja-jp/library/ded0dc5s(VS.80).aspx
.InternalBufferSize = 4092
' NotifyFilter に設定する値によって、通知の種類を選択する。
' 今回は全部設定してみた。
.NotifyFilter = System.IO.NotifyFilters.Attributes Or _
System.IO.NotifyFilters.CreationTime Or _
System.IO.NotifyFilters.DirectoryName Or _
System.IO.NotifyFilters.FileName Or _
System.IO.NotifyFilters.LastAccess Or _
System.IO.NotifyFilters.LastWrite Or _
System.IO.NotifyFilters.Security Or _
System.IO.NotifyFilters.Size
.EnableRaisingEvents = True ' 監視する
.EndInit()
End With
End Sub
' ディレクトリ(IncludeSubdirectories=True の時のみ)またはファイルが作成された
Private Sub FileSystemWatcher1_Created(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Created
Me.Notify("FileSystemWatcher1.Created", e)
End Sub
' ディレクトリ(IncludeSubdirectories=True の時のみ)またはファイルのサイズ、
' システム属性、最終書き込み時刻、最終アクセス時刻、または NTFS セキュリティ アクセス許可が変更
Private Sub FileSystemWatcher1_Changed(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Changed
Me.Notify("FileSystemWatcher1.Changed", e)
End Sub
' ディレクトリ(IncludeSubdirectories=True の時のみ)またはファイルの名前が変更された
Private Sub FileSystemWatcher1_Renamed(ByVal sender As Object, ByVal e As System.IO.RenamedEventArgs) Handles FileSystemWatcher1.Renamed
With Me.ListBox1.Items
.Add(StrDup(20, "="))
.Add("◆FileSystemWatcher1.Renamed◆")
.Add("ChangeType:" & e.ChangeType.ToString())
.Add("OldFullPath:" & e.OldFullPath)
.Add("OldName:" & e.OldName)
.Add("FullPath:" & e.FullPath)
.Add("Name:" & e.Name)
End With
' 更に詳細な情報を得る
Dim info As System.IO.FileSystemInfo = New System.IO.FileInfo(e.FullPath)
System.Diagnostics.Debug.WriteLine("Attributes:" & info.Attributes.ToString())
If info.Attributes = IO.FileAttributes.Directory Then
System.Diagnostics.Debug.WriteLine("DirectoryName:" & System.IO.Path.GetFileName(e.FullPath))
Else
System.Diagnostics.Debug.WriteLine("LastName:" & System.IO.Path.GetFileName(e.FullPath))
End If
System.Diagnostics.Debug.WriteLine("CreationTimeUtc:" & info.CreationTimeUtc.ToString())
System.Diagnostics.Debug.WriteLine("LastAccessTimeUtc:" & info.LastAccessTimeUtc.ToString())
End Sub
' バッファオーバーフロー時に発生する
Private Sub FileSystemWatcher1_Error(ByVal sender As Object, ByVal e As System.IO.ErrorEventArgs) Handles FileSystemWatcher1.Error
With Me.ListBox1.Items
.Add(StrDup(20, "="))
.Add("◆FileSystemWatcher1.Error◆")
.Add("Exception Name:" & e.GetException().GetType.Name)
.Add("Exception Message:" & e.GetException().Message)
End With
End Sub
' ディレクトリ(IncludeSubdirectories=True の時のみ)または削除が作成された
Private Sub FileSystemWatcher1_Deleted(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Deleted
Me.Notify("FileSystemWatcher1.Deleted", e)
End Sub
Private Sub Notify(ByVal eventName As String, ByVal e As System.IO.FileSystemEventArgs)
With Me.ListBox1.Items
.Add(StrDup(20, "="))
.Add("◆" & eventName & "◆")
.Add("ChangeType:" & e.ChangeType.ToString())
.Add("FullPath:" & e.FullPath)
.Add("Name:" & e.Name)
End With
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' 違う PC の監視を同期で行う
Dim noteWatcher As System.IO.FileSystemWatcher = New System.IO.FileSystemWatcher
With noteWatcher
.BeginInit()
.Path = REMOTE_PATH
.Filter = "*.txt" ' テキストファイルだけ監視する。"wankuma.txt" のようにファイル名を直接指定してもOK
.IncludeSubdirectories = False ' サブディレクトリは含まない
' 最終アクセス日時、最終更新日時、ファイル名の変更 を通知
.NotifyFilter = System.IO.NotifyFilters.LastAccess Or _
System.IO.NotifyFilters.LastWrite Or _
System.IO.NotifyFilters.FileName
.SynchronizingObject = Me
.EnableRaisingEvents = True ' 監視する
.EndInit()
End With
' 以下、同期通信による監視
Dim result As System.IO.WaitForChangedResult = _
noteWatcher.WaitForChanged(IO.WatcherChangeTypes.All)
With Me.ListBox1.Items
.Add(StrDup(20, "="))
.Add("◇WaitForChanged◇")
.Add("TimedOut:" & result.TimedOut)
.Add("ChangeType:" & result.ChangeType.ToString())
.Add("OldName:" & result.OldName)
.Add("Name:" & result.Name)
End With
noteWatcher.EnableRaisingEvents = False
noteWatcher.Dispose()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
' 監視をやめる
Me.FileSystemWatcher1.EnableRaisingEvents = False
End Sub
End Class