Search code examples
c#processstack-tracefilesystemwatcherwindows-defender

FIleSystemWatcher IOException


I have a Windows Service that monitors a folder for new files and runs a process. However, the service crashes every time I drop files into the monitored folder. Here is the Exception I am receiving:

Application: Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.IO.IOException Stack: at System.IO._Error.WinIOError(Int32, System.String) at System.IO._Error.WinIOError() at System.IO.File.Move(System.String, System.String) at Service.Service.Process(System.String, System.String) at Service.Service.OnChanged(System.Object, System.IO.FileSystemEventArgs) at System.IO.FileSystemWatcher.OnCreated(System.IO.FileSystemEventArgs)
at System.IO.FileSystemWatcher.NotifyFileSystemEventArgs(Int32, System.String) at System.IO.FileSystemWatcher.CompletionStatusChanged(UInt32, UInt32, System.Threading.NativeOverlapped*) at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)

Everything was working fine and then all of the sudden, it crashes every time I use it. I don't remember changing anything that would cause this. Here is my code:

public Service()
{
    InitializeComponent();
}

protected override void OnStart(string[] args)
{
    FileSystemWatcher watcher = new FileSystemWatcher(ConfigurationManager.AppSettings["UploadPath"]);

    watcher.Created += new FileSystemEventHandler(OnChanged);
    watcher.EnableRaisingEvents = true;
}

public static void OnChanged(object source, FileSystemEventArgs e)
{
    Process(e.Name, e.FullPath);
}

public static void Process(string fileName, string path)
{
    string newPath = Path.Combine(ConfigurationManager.AppSettings["NewPath"], fileName);

    Process process = new Process();

    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardOutput = true;
    process.StartInfo.FileName = @"C:\Program Files\Microsoft Security Client\Antimalware\mpcmdrun";
    process.StartInfo.Arguments = " -scan -scantype 3 -file L:\\Test\\";

    process.Start();

    string output = process.StandardOutput.ReadToEnd();
    process.WaitForExit();

    if (process.ExitCode == 0)
    {
        File.Move(path, cleanPath);
    }

    else
    {
        TextWriter tw = new StreamWriter(ConfigurationManager.AppSettings["FailedPath"] + fileName + ".txt");
        tw.WriteLine(output);
        tw.Close();

        File.Delete(path);
    }
}
protected override void OnStop()
{

}

Solution

  • I added Thread.Sleep(5000) before the creation of the process. This works well but it does at 5 seconds to the scanning of each file. And, as people have stated people, it feels kind of hackish.