Windows Services: File Watcher Implementation

File Watcher

File Watcher is an application that continuously monitor your files. You can define files or a whole directory to look after, and have a custom action that notifies you every time those files/directory have been changed (created, deleted, renamed or error had occurred).

Simple Implementation Steps:

1. Create a new FileWatcher and define values for its properties

FileWatcher watcher = new FileWatcher();
watcher.Path = Path.GetDirectoryName(file); 
watcher.Filter = Path.GetFileName(file);
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
           | NotifyFilters.FileName | NotifyFilters.DirectoryName;
  • Path of the directory to be monitored.
  • Filter: “.txt” only watch text files, “GetFileName(file)” only watch that specific file.
  • NotifyFilter: watch for changes in LastAccess, LastWrite, FileName, DirectoryName

2. Subscribe to Event Handlers
These will notify the user if there are changes to the file/directory the FileWatcher is watching.

watcher.Changed += FileChanged;
watcher.Renamed += FileRenamed;
watcher.Created += FileChanged;
watcher.Deleted += FileChanged;
private void FileRenamed( object sender, RenamedEventArgs e )
{
 Debug.WriteLine( string.Format( " {0} renamed to {1} at {2}", e.OldFullPath, e.FullPath, DateTime.Now.ToString( "MM/dd/yy H:mm:ss" ) ) );
}

private void FileChanged( object sender, FileSystemEventArgs e )
{
 Debug.WriteLine( string.Format( "{0} with path {1} has been {2} at {3}", e.Name, e.FullPath, e.ChangeType, DateTime.Now.ToString( "MM/dd/yy H:mm:ss" ));
}

3. Enable the FileWatcher.
NOTE: When Path is not set and EnableRaisingEvent is not set to true, specified file/directory will not be watched.

watcher.EnableRaisingEvents = true;

FileWatcher + Windows Services

Windows Services allows us to run assembly in the background. They are very suitable for the times when you need to continuously listen to incoming network connections, or monitor a directory or files.
Let’s make a Windows Service project by doing File -> New Project -> Windows Service
Do not forget to inherit from ServiceBase().

  • By default, we already have the Run() in Program.cs that creates an instance of our FileWatcherService class.
    ServiceBase[] ServicesToRun;
    ServicesToRun = new ServiceBase[]
       {
          new FileWatcherService()
       };
    ServiceBase.Run(ServicesToRun);
    
  • When we start our service, the service will call the OnStart() inside our FileWatcherService().

  • Like what was described above this post, we create an instance of the FileWatcher on OnStart() and subscribe to the events.
    OnStop(), we dispose the FileWatcher instance and unsubscribe to the events.

    protected override void OnStart( string[] args )
    {
    _fileWatcher = new FileWatcher( currentDirectory );
    _fileWatcher.Changed += FileChanged;
    _fileWatcher.EnableRaisingEvents = true;
    }
    
    protected override void OnStop()
    {
    _fileWatcher.Changed -= FileChanged;
    _fileWatcher.EnableRaisingEvents = false;
    _fileWatcher.Dispose();
    }
    
  • a. Create an Installer: Add -> new Class
    b. After creating a new class, inherit the class from Installer [add reference to System.Configuration.Install]
    c. Create a new ServiceProcessInstaller() and ServiceInstaller — These install an executable that extend ServiceBase(), which is our FileWatcherService.
    d. Set the properties: ServiceName, Account, StartType, DisplayName, etc.
    NOTE: Set the ServiceName to be the same as the value of the ServiceName on the service itself.
    e. Add the 2 installers to the Installers collection.

    ServiceProcessInstaller processInstaller = new ServiceProcessInstaller();
    ServiceInstaller serviceInstaller = new ServiceInstaller();
    processInstaller.Account = ServiceAccount.NetworkService;
    serviceInstaller.DisplayName = "File Watcher Service";
    serviceInstaller.StartType = ServiceStartMode.Manual;
    serviceInstaller.ServiceName = "File Watcher Service";
    Installers.AddRange(new Installer[]
    {
      processInstaller, serviceInstaller
    });
    
  • Install the service and start running it!
    a. Run Command Prompt [Visual Studio Command Prompt or Windows SDK Command Prompt] as Administrator.
    b. Go to the directory where the Windows Service executable is at.
    c. Type installutil {name of the service} (e.g. installutil FileWatcherService.exe).
    d. On Success, you will be able to see the Service on your Local Services list.
    Windows Service

    Windows Service successfully installed


    e. To uninstall: type installutil /u {name of the service}

2 thoughts on “Windows Services: File Watcher Implementation

    • By default, FileSystemWatcher uses small InternalBufferSize to increase performance, and if there are too many changes occurring in a short time frame, it will cause overflow. Instead, you can increase the FileSystemWatcher.InternalBufferSize to take care of that many files. Just do not increase it too much because it can be expensive. Try also using NotifyFilter and IncludeSubdirectories properties to help getting the files you need and filtering out those you don’t want.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>