FIleSystemWatcher IOException - PullRequest
       11

FIleSystemWatcher IOException

3 голосов
/ 31 августа 2011

У меня есть служба Windows, которая отслеживает папку для новых файлов и запускает процесс. Однако служба падает каждый раз, когда я помещаю файлы в контролируемую папку. Вот исключение, которое я получаю:

Приложение: Framework Версия: v4.0.30319 Описание: Процесс было прекращено из-за необработанного исключения. Информация об исключении: Стек исключений System.IO.IOException: в System.IO ._ Error.WinIOError (Int32, System.String) в System.IO. _Error.WinIOError () в System.IO.File.Move (System.String, System.String) в Service.Service.Process (System.String, System.String) в Service.Service.OnChanged (System.Object, System.IO.FileSystemEventArgs) в System.IO.FileSystemWatcher.OnCreated (System.IO.FileSystemEventArgs)
в System.IO.FileSystemWatcher.NotifyFileSystemEventArgs (Int32, System.String) в System.IO.FileSystemWatcher.CompletionStatusChanged (UInt32, UInt32, System.Threading.NativeOverlapped *) в System.Threading._IOCompletionCallback.PerformIOCompletionCallback (UInt32, UInt32, System.Threading.NativeOverlapped *)

Все работало нормально, а потом внезапно зависает каждый раз, когда я его использую. Я не помню, чтобы что-нибудь изменилось Вот мой код:

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()
{

}

Ответы [ 4 ]

1 голос
/ 31 августа 2011

Я подозреваю, что в некоторых случаях процесс все еще имеет блокировку файла.Просто интересно, почему вы не звоните:

process.Close(); // Frees all the resources that are associated with this component

после WaitForExit ().

0 голосов
/ 02 сентября 2011

Может ли быть так, что другой процесс, скажем, другой экземпляр сканера, который вы запускаете вручную, все еще удерживает блокировку файла в тот момент, когда вы пытаетесь его переместить?

Вы должны использовать Process Monitor , чтобы увидеть, какие процессы обращаются к файлу.

В любом случае, вы не сканируете новый файл, вы всегда сканируете всю папку L: \ Test. Это твое намерение?

0 голосов
/ 02 сентября 2011

Я добавил Thread.Sleep (5000) перед созданием процесса.Это работает хорошо, но это делает на 5 секунд для сканирования каждого файла.И, как утверждают люди, это выглядит как хакерство.

0 голосов
/ 31 августа 2011

Почему вы не выполняете следующие проверки только после того, как убедитесь, что процесс существует с 0, например,

if (process.ExitCode == 0)
{
    process.Close();
    process.Dispose();
    if (File.Exists(path+filename) && !IsFileLocked(fileInfo) && Directory.Exists(cleanPath))
        File.Move(path, cleanPath);
}

Я сомневаюсь, что процесс сканирования все еще помещает файл в карантин, пока вы пытаетесь переместить.

ссылка: знаете, как проверить, заблокирован ли файл?

И, конечно же, вы должны правильно обрабатывать другие условия ...

...