问题
I have a FileSystemWatcher object in a Windows service. I wrote it in a console application using that app as a stub for my component.
My component instantiates the FileSystemWatcher and sets up to watch a mapped drive. This works great for me from both the test stub Console App and the Deployable Windows Service.
I also have the onError event hooked up with log4net logging a FATAL level error:
public FileSystemWatcher CreateFileWatcher()
{
FileSystemWatcher watcher = new FileSystemWatcher();
try
{
log.Info("Configuring DPIFileWatcher");
watcher.Filter = "*.xml";
log.Info("DPIFileWatcher Filter set to: *.xml");
string watcherPath = ConfigurationManager.AppSettings["InoundPath"].ToString();
watcher.Path = watcherPath;
log.Info(String.Format("DPIFileWatcher Path set to: {0}", watcherPath));
watcher.Created += new FileSystemEventHandler(DPIWatcher_FileCreated);
watcher.Changed += new FileSystemEventHandler(DPIWatcher_FileChanged);
watcher.Error += new ErrorEventHandler(DPIWatcher_Error);
watcher.EnableRaisingEvents = true;
log.Info("DPIFileWatcher Configuration Successful.");
}
catch(Exception e)
{
log.Fatal(String.Format("Failed to configure DPIFileWatcher: {0}", e.Message));
}
return watcher;
}
Here is my error event:
private void DPIWatcher_Error(object source, ErrorEventArgs e)
{
log.Fatal(String.Format("FileWatacher error: {0}", e.GetException().Message));
}
If I test for a network error loss by unplugging the network card, I get the following log error from my console app:
FATAL [ 12] 2013-02-12 12:14:02,142 SMILLER-E6430 METHOD: DPIWatcher_Error GenFileWatch.DPIFileWatcher- FileWatacher error: The specified network name is no longer available (C:\Development\GenFileWatch\GenFileWatch\DPIFileWatcher.cs: 447)
But this log error will not work when running from within a Windows service.
Does anyone have any idea why or how to fix?
回答1:
First of all, is your service running with an account that has access to the directory you're trying to monitor. 99% of the time, running a "console" app and running a "service" run under two different user contexts. If that user context has no access to that directory (or the URL only means something in another user context), I don't think OnError would be invoked.
Second, FileSystemWatcher
is fairly unreliable. It works, most of the time, but sometimes doesn't. It uses the underlying native function `` which is documented with
When you first call ReadDirectoryChangesW, the system allocates a buffer to store change information. This buffer is associated with the directory handle until it is closed and its size does not change during its lifetime. Directory changes that occur between calls to this function are added to the buffer and then returned with the next call. If the buffer overflows, the entire contents of the buffer are discarded, the lpBytesReturned parameter contains zero, and the ReadDirectoryChangesW function fails with the error code ERROR_NOTIFY_ENUM_DIR
来源:https://stackoverflow.com/questions/14838885/filesystemwatcher-onerror-is-not-working-from-windows-service