Window Service For Monitor multiple folders using FileSystemWatcher

Dotnet has a class named FileSystemWatcher that is for having watch in a particular folder and sub folder (conditional), when a file created, modified, deleted or renamed , it fires respective event where we can implement our logic to prevent suspicious activity.

Below is the file inspector service that watch in multiple folder as define in the XML configuration setting file,
If any new file created or renamed rather than the extension given in XML configuration setting file, will be deleted and other changes , file deleted will be logged in log file.

using System;
using System.Diagnostics;
using System.ServiceProcess;
using System.IO;
using System.Collections;
using System.Text;

namespace FileInspector
{
public partial class FileInspectorService : ServiceBase
{
       
  public FileInspectorService()
  {
      InitializeComponent();
  }
  protected override void OnStart(string[] args)
  {
    Global.WriteLog(string.Format("Service Start At {0}",DateTime.Now.ToString("dd MMMM yyyy hh:mm:ss")));
    try
    {
      //System.Diagnostics.Debugger.Launch();
    foreach (string sMonitorFolder in Global.DirectoryToWatch())
    {    
      if (Directory.Exists(sMonitorFolder))
      {
         FileSystemWatcher fileSysetmWatcher = new FileSystemWatcher();
         fileSysetmWatcher.Path = sMonitorFolder;
         fileSysetmWatcher.Filter = "*.*";
         fileSysetmWatcher.IncludeSubdirectories = true;
         fileSysetmWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.DirectoryName;
         fileSysetmWatcher.Created += new FileSystemEventHandler(fileSysetmWatcher_created);
         fileSysetmWatcher.Deleted += new FileSystemEventHandler(fileSysetmWatcher_deleted);
         fileSysetmWatcher.Renamed += new RenamedEventHandler(fileSysetmWatcher_Renamed);
         fileSysetmWatcher.Changed += new FileSystemEventHandler(fileSysetmWatcher_Changed);
         fileSysetmWatcher.EnableRaisingEvents = true;
      }
    }
   }
    catch (Exception ex)
    {
        Global.WriteLog("Error: " + ex.Message);
    }
  }
  /// <summary>
  /// Check Performance of the Applocation.
  /// </summary>
  void checkPerformance()
  {
    PerformanceCounter cpuCounter;
    PerformanceCounter ramCounter;

    cpuCounter = new PerformanceCounter();

    cpuCounter.CategoryName = "Processor";
    cpuCounter.CounterName = "% Processor Time";
    cpuCounter.InstanceName = "_Total";

    ramCounter = new PerformanceCounter("Memory", "Available MBytes");
    string cpuUses = cpuCounter.NextValue() + "%";
    string ram = ramCounter.NextValue() + "MB";

    Console.WriteLine("Cpu Uses " + cpuUses + "\n" + "Memory Uses  " + ram);
  }
  //Invoke when a Create event would be performed
  void fileSysetmWatcher_created(object sender, FileSystemEventArgs e)
  {
    if (Global.GetFileExtention(e.FullPath))
        Global.WriteLog(string.Format("New File {0} Created On {1} ", DateTime.Now.ToString("dd MMMM yyyy hh:mm:ss"), e.FullPath));
    else
    {
      try
      {
          System.Threading.Thread.Sleep(1000);
          File.Delete(e.FullPath);
          Global.WriteLog(string.Format("New File {0} Deleted On {1} ", DateTime.Now.ToString("dd MMMM yyyy hh:mm:ss"), e.FullPath));
      }
      catch (Exception ex)
      {
          Global.WriteLog(string.Format("Error On File {0} Deletion On {1} :: {2} ", DateTime.Now.ToString("dd MMMM yyyy hh:mm:ss"), e.FullPath, ex.Message));
      }
    }
    return;
  }
   
  /// <summary>
  /// fileSysetmWatcher_deleted: Fired when the Watcher object detects a folder/file delete event.
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  void fileSysetmWatcher_deleted(object sender, FileSystemEventArgs e)
  {
    //Console.WriteLine(DateTime.Now + ": deleted:" + e.FullPath);
    Global.WriteLog("deleted:" + e.FullPath);

  }
  /// <summary>
  /// fileSysetmWatcher_Changed: Fired when the Watcher object detects a folder/file change event.
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  //Invoke when a  changed event would be performed
  void fileSysetmWatcher_Changed(object sender, FileSystemEventArgs e)
  {
    if (Global.GetFileExtention(e.FullPath))
        Global.WriteLog(e.ChangeType + ": " + e.FullPath);
  }
  /// <summary>
  /// fileSysetmWatcher_Renamed
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  //Invoke when a  Renamed event would be performed
  void fileSysetmWatcher_Renamed(object sender, RenamedEventArgs e)
  {
   //Global.WriteLog(e.ChangeType + " from " + e.OldFullPath + " to " + e.Name);
   try
   {
     if (!Global.GetFileExtention(e.FullPath))
     {
         System.Threading.Thread.Sleep(500);
         File.Delete(e.FullPath);
         Global.WriteLog(string.Format("Renaming File {0} Deleted file Name {1} ", DateTime.Now.ToString("dd MMMM yyyy hh:mm:ss"), e.FullPath));
     }
     else
         Global.WriteLog(string.Format("Renaming File {0} New Name  On {1} ", DateTime.Now.ToString("dd MMMM yyyy hh:mm:ss"), e.FullPath));
        
   }
   catch (Exception ex)
   {
       Global.WriteLog(string.Format("Error On File {0} Renaming On {1} :: {2} ", DateTime.Now.ToString("dd MMMM yyyy hh:mm:ss"), e.FullPath,ex.Message));
   }
  }
  /// <summary>
  ///
  /// </summary>
  protected override void OnStop()
  {
      Global.WriteLog(string.Format("Service Stop At {0}", DateTime.Now.ToString("dd MMMM yyyy hh:mm:ss")));
  }
}

}

Global Class : Reads the setting from configuration XML file like which directory to be watch, which file extension to be prevent and which file is treated as suspicious file.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
using System.Reflection;
using System.Collections;

namespace FileInspector
{
/// <summary>
/// Global Class :
/// Writes the all activity in a Log file and saves it in a specified location.
/// </summary>
static class Global
{
 static string output;
 static List<string> filter;
 static XmlDocument doc;

 /// <summary>
 ///
 /// </summary>
 static Global()
 {
   doc = new XmlDocument();
   doc.Load(Path.Combine(Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName, "setting.xml"));
   //doc.Load(Path.Combine(System.Reflection.Assembly.GetExecutingAssembly().Location, "setting.xml"));

   output = doc.SelectSingleNode("/root/LogFilePath/value").InnerText;
   filter = new List<string>();
   XmlNodeList exNodeList = doc.SelectNodes("/root/FileExtension/value");
   foreach (XmlNode nd in exNodeList)
       filter.Add(nd.InnerText);
 }
 /// <summary>
 /// Log : methods for performing the log write
 /// </summary>
 /// <param name="Message"></param>
 public static void WriteLog(string Message)
 {
   DateTime dateTime = System.DateTime.UtcNow.AddMinutes(330);
   if (!Directory.Exists(output))
       Directory.CreateDirectory(output);

   string logfileName =  dateTime.ToString("dd_MMM_yy") + "_" + ".txt";
   StreamWriter streamwriter = new StreamWriter(output + logfileName, true);
   streamwriter.WriteLine(DateTime.Now + ": " + Message);
   streamwriter.Close();
   streamwriter.Dispose();

 }
 /// <summary>
 /// DirectoryArray : List of all the directory that required to be watched.
 /// </summary>
 /// <returns>Array</returns>
 public static Boolean GetFileExtention(string filePath)
 {
   string fileEX = Path.GetExtension(filePath);
   return filter.Contains(fileEX);
 }
 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 public static List<string> DirectoryToWatch()
 {
   List<string> liFolderToWatch = new List<string>();
   XmlNodeList ndWatchFolders = doc.SelectNodes("/root/FolderToWatch/value");
   foreach (XmlNode nd in ndWatchFolders)
       liFolderToWatch.Add(nd.InnerText);

   return liFolderToWatch;
 }
}

}

Configuration XML setting file :- Add folder to watch in FolderToWatch tag, define file extension that to be prevent and other than this will be suspicious file for this service and taken appropriate action by service, define log folder where log file to be written.
<root>
  <FolderToWatch>
    <value>D:/Test</value>
    <value>D:/Images</value>
    <value>D:/Data</value>
  </FolderToWatch>
  <FileExtension>
    <value>.aspx</value>
    <value>.ascx</value>
    <value>.css</value>
    <value>.js</value>
    <value>.jpg</value>
    <value>.html</value>
    <value>.png</value>
  </FileExtension>
  <LogFilePath>
    <value>D:/FileWatcherLog/</value>
  </LogFilePath>

</root>

DownLoad File Watcher Window Service Full Code:

Download FileWatcherWindowService

Recent Article