1

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?

Sam
  • 4,766
  • 11
  • 50
  • 76
  • Do you create the FileSystemWatcher instance from `OnStart`? What do you do with the reference after you have created it? It might ge collected prematurely, thus the event never fires. Just a guess though. – Christian.K Feb 12 '13 at 18:57

1 Answers1

0

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

Peter Ritchie
  • 35,463
  • 9
  • 80
  • 98
  • Thanks for the feedback. On your first comment though, we obviously have access to the file share through the Windows Service because the main functionality works fine in the service. The fileserver listens for new files in the folder on the mapped drive, and the created event is fired and we do what we want to do there. So the Win Service has access to that drive. And so we can not figure out why onerror will not tell us "The specified network name is no longer available" from the win service like it does from the Console App. – Sam Feb 13 '13 at 13:43
  • Also, on your second comment, we just started testing for this, but I read you can increase the buffer size to corrrect this. Although to much is bad for performance. So it is trial and error to get it just right. – Sam Feb 13 '13 at 13:45