I need to process a number of directories and process files as they are created or renamed. To do this I created the following Watcher Class.
public class Watcher
{
FileSystemWatcher fileSystemWatcher = null;
public delegate void FileCreatedEventHandler(object sender, FileSystemEventArgs e);
public delegate void FileRenamedEventHandler(object sender, RenamedEventArgs e);
public delegate void LogEventHandler(object sender, String e);
public event FileCreatedEventHandler FileCreated;
public event FileRenamedEventHandler FileRenamed;
public event LogEventHandler LogEvent;
public String Directory { get; set; }
public String DAP { get; set; }
public String Filter { get; set; }
public Watcher()
{
fileSystemWatcher = new FileSystemWatcher();
}
public Watcher(String directory, String filter, String dap)
{
this.DAP = dap;
this.Directory = directory;
this.Filter = filter;
}
public void StartWatch()
{
if (fileSystemWatcher == null) fileSystemWatcher = new FileSystemWatcher();
fileSystemWatcher.Filter = Filter;
fileSystemWatcher.Path = Directory;
fileSystemWatcher.EnableRaisingEvents = true;
fileSystemWatcher.Created += FileSystemWatcher_Created;
fileSystemWatcher.Renamed += FileSystemWatcher_Renamed;
Log(String.Format("Watching Directory {0}", Directory));
}
private void FileSystemWatcher_Renamed(object sender, RenamedEventArgs e)
{
FileRenamed?.Invoke(sender, e);
}
private void FileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
FileCreated?.Invoke(sender, e);
}
private void Log ( String Message )
{
LogEvent?.Invoke(this, Message);
}
}
That in turn is used by the following function, which sets up a number of instances; one for each of the directories being watched.
public ProfileWatcher()
{
List<nhs_acquisition_profile> p = null;
List <Watcher> fwList = new List<Watcher>();
InitializeComponent();
try
{
if (!System.Diagnostics.EventLog.SourceExists("DirectoryScanner"))
{
System.Diagnostics.EventLog.CreateEventSource(
"DirectoryScanner","ProfileDirectoryScanner");
}
//
profileWatcherLog.Source = "DirectoryScanner";
profileWatcherLog.Log = "ProfileDirectoryScanner";
using (nhs_acquisition_profiles profiles = new nhs_acquisition_profiles(Properties.Settings.Default.DataConnection))
{
profileWatcherLog.WriteEntry("retrieving list of DAP Profiles");
p = profiles.Select<nhs_acquisition_profile>(null);
profileWatcherLog.WriteEntry(String.Format("Found {0} Directories to watch.", p.Count.ToString()));
foreach (nhs_acquisition_profile pfl in p)
{
Watcher w = null;
try
{
profileWatcherLog.WriteEntry(String.Format("Attempting to set-up watcher on {0} for DAP {1}",pfl.dap_file_location,pfl.dap_name));
w = new Watcher(pfl.dap_file_location, "*.*", pfl.dap_name);
profileWatcherLog.WriteEntry("Initialising Event Handlers");
// initialise event handlers
w.FileCreated += W_FileCreated;
w.FileRenamed += W_FileRenamed;
w.LogEvent += W_LogEvent;
profileWatcherLog.WriteEntry("Event Handlers initialised");
w.StartWatch();
profileWatcherLog.WriteEntry("Watch started....Adding to Watcher List");
// add the watcher to the list of watchers
fwList.Add(w);
profileWatcherLog.WriteEntry("Added to list of file watchers");
profileWatcherLog.WriteEntry(String.Format("Watching {0} for files matching *.* for DAP {1}",pfl.dap_file_location,pfl.dap_name));
}
catch
{
throw;
}
}
}
}
catch (Exception e)
{
profileWatcherLog.WriteEntry(String.Format("ERROR: {0}",e.Message),EventLogEntryType.Error);
}
finally
{
profileWatcherLog.WriteEntry("Profile Watcher setup");
}
}
Each time a file is created it should call one of the following
private void W_FileRenamed(object sender, RenamedEventArgs e)
{
try
{
profileWatcherLog.WriteEntry(String.Format("File Renamed From {0} to {1}", e.OldName, e.Name));
using (FileSystemWatcher watcher = ((System.IO.FileSystemWatcher)sender))
{
if (watcher != null)
Process(watcher.Path);
}
}
catch (System.Exception ex)
{
profileWatcherLog.WriteEntry(ex.Message, EventLogEntryType.Error);
}
finally
{
}
}
private void W_FileCreated(object sender, FileSystemEventArgs e)
{
try
{
profileWatcherLog.WriteEntry(String.Format("File Created {0}", e.Name));
using (FileSystemWatcher watcher = ((System.IO.FileSystemWatcher)sender))
{
if (watcher != null)
Process(watcher.Path);
}
}
catch ( System.Exception ex)
{
profileWatcherLog.WriteEntry(ex.Message, EventLogEntryType.Error);
}
finally
{
}
}
This is fine for the first time a file is dropped into a target directory. The trouble is it is resetting the EnableRaisingEvents once it returns from the
FileCreated?.Invoke(sender, e);
Line in the first listing above.
Nothing in the code seems to be doing this and when I try and reset it back after the FileCreated it then moans that the object has been disposed (even though the debugger shows it has a value)
The whole thing is then wrapped in a service, so that it runs all the time.