132 lines
4.5 KiB
VB.net
132 lines
4.5 KiB
VB.net
Imports System.IO
|
|
Imports DigitalData.Modules.Base.FileWatcherFilters
|
|
Imports Digitaldata.Modules.Logging
|
|
|
|
|
|
Public Class FileWatcher
|
|
' Internals
|
|
Private ReadOnly _Logger As Logger
|
|
Private ReadOnly _Watchers As List(Of FileSystemWatcher)
|
|
Private ReadOnly _Files As Dictionary(Of String, FileWatcherProperties)
|
|
Private ReadOnly _Filters As List(Of BaseFileFilter)
|
|
|
|
' Options
|
|
Private _Path As String
|
|
|
|
' Public Events
|
|
Public Event FileSaved(ByVal FullName As String, ByVal IsSpecial As Boolean)
|
|
|
|
Public Sub New(LogConfig As LogConfig, Path As String, Optional Filters As List(Of BaseFileFilter) = Nothing)
|
|
_Logger = LogConfig.GetLogger()
|
|
_Files = New Dictionary(Of String, FileWatcherProperties)
|
|
_Watchers = New List(Of FileSystemWatcher)
|
|
_Filters = IIf(IsNothing(Filters), GetDefaultFilters(), Filters)
|
|
_Path = Path
|
|
|
|
For Each oFilePath In Directory.EnumerateFiles(_Path)
|
|
Try
|
|
If IO.File.Exists(oFilePath) Then
|
|
_Files.Add(oFilePath, New FileWatcherProperties With {
|
|
.CreatedAt = DateTime.Now,
|
|
.ChangedAt = Nothing
|
|
})
|
|
End If
|
|
Catch ex As Exception
|
|
_Logger.Error(ex)
|
|
_Logger.Warn("File {0} cannot be watched!")
|
|
End Try
|
|
Next
|
|
End Sub
|
|
|
|
Public Sub Add(Filter As String)
|
|
_Watchers.Add(CreateWatcher(Filter))
|
|
End Sub
|
|
|
|
Public Sub Start()
|
|
For Each oWatcher In _Watchers
|
|
oWatcher.EnableRaisingEvents = True
|
|
Next
|
|
End Sub
|
|
|
|
Public Sub [Stop]()
|
|
For Each oWatcher In _Watchers
|
|
If Not IsNothing(oWatcher) Then
|
|
oWatcher.EnableRaisingEvents = False
|
|
oWatcher.Dispose()
|
|
End If
|
|
Next
|
|
End Sub
|
|
|
|
Private Function GetDefaultFilters()
|
|
Return New List(Of BaseFileFilter) From {
|
|
New TempFileFilter,
|
|
New OfficeFileFilter
|
|
}
|
|
End Function
|
|
|
|
Private Function CreateWatcher(Filter As String)
|
|
Dim oWatcher = New FileSystemWatcher() With {
|
|
.Path = _Path,
|
|
.Filter = Filter,
|
|
.NotifyFilter = NotifyFilters.LastAccess _
|
|
Or NotifyFilters.LastWrite _
|
|
Or NotifyFilters.FileName _
|
|
Or NotifyFilters.Size _
|
|
Or NotifyFilters.FileName _
|
|
Or NotifyFilters.Attributes
|
|
}
|
|
|
|
AddHandler oWatcher.Created, AddressOf HandleFileCreated
|
|
AddHandler oWatcher.Changed, AddressOf HandleFileChanged
|
|
AddHandler oWatcher.Deleted, AddressOf HandleFileDeleted
|
|
AddHandler oWatcher.Renamed, AddressOf HandleFileRenamed
|
|
|
|
Return oWatcher
|
|
End Function
|
|
|
|
Private Sub HandleFileCreated(sender As Object, e As FileSystemEventArgs)
|
|
_Files.Add(e.FullPath, New FileWatcherProperties())
|
|
_Logger.Debug("[Created] " & e.FullPath)
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' This may fire twice for a single save operation,
|
|
''' see: https://blogs.msdn.microsoft.com/oldnewthing/20140507-00/?p=1053/
|
|
''' </summary>
|
|
Private Sub HandleFileChanged(sender As Object, e As FileSystemEventArgs)
|
|
_Files.Item(e.FullPath).ChangedAt = DateTime.Now
|
|
_Logger.Debug("[Changed] " & e.FullPath)
|
|
|
|
Dim oShouldRaiseSave As Boolean = Not _Filters.Any(Function(oFilter)
|
|
Return oFilter.ShouldFilter(e)
|
|
End Function)
|
|
|
|
If oShouldRaiseSave Then
|
|
RaiseEvent FileSaved(e.FullPath, False)
|
|
End If
|
|
End Sub
|
|
Private Sub HandleFileDeleted(sender As Object, e As FileSystemEventArgs)
|
|
_Files.Remove(e.FullPath)
|
|
_Logger.Debug("[Removed] " & e.FullPath)
|
|
End Sub
|
|
|
|
Private Sub HandleFileRenamed(sender As Object, e As RenamedEventArgs)
|
|
Dim oProperties = _Files.Item(e.OldFullPath)
|
|
_Files.Remove(e.OldFullPath)
|
|
_Files.Add(e.FullPath, oProperties)
|
|
' Soll eine umbenannte datei als NEU gelten?
|
|
|
|
Dim oShouldRaiseSave = _Filters.Any(Function(oFilter)
|
|
Return oFilter.ShouldRaiseSave(e)
|
|
End Function)
|
|
|
|
If oShouldRaiseSave Then
|
|
RaiseEvent FileSaved(e.OldFullPath, True)
|
|
End If
|
|
|
|
_Logger.Debug("[Renamed] {0} --> {1}", e.OldFullPath, e.FullPath)
|
|
End Sub
|
|
|
|
|
|
End Class
|