FIleSystemWatcher IOException
У меня есть служба 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._IbackInt32PlayerCformColtionCopy 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 ответа
Я добавил Thread.Sleep(5000) перед созданием процесса. Это работает хорошо, но это делает на 5 секунд для сканирования каждого файла. И, как утверждают люди, это выглядит как хакерство.
Я подозреваю, что процесс по-прежнему имеет блокировку файла в некоторых случаях. Просто интересно, почему ты не звонишь
process.Close(); // Frees all the resources that are associated with this component
после WaitForExit().
Может ли быть так, что другой процесс, скажем, другой экземпляр сканера, который вы запускаете вручную, все еще удерживает блокировку файла в тот момент, когда вы пытаетесь его переместить?
Вы должны использовать Process Monitor, чтобы увидеть, какие процессы обращаются к файлу.
В любом случае, вы не сканируете новый файл, вы всегда сканируете всю папку L:\Test. Это твое намерение?
Две хитрости, которые кажутся необходимыми при работе с MpCmdRun:
Включают
-DisableRemediation
в ваш список параметров при вызовеMpCmdRun
. Это заставляет процесс запускаться очень быстро и сообщать результаты черезStandardOutput
.Игнорируйте возвращенный код выхода. Вместо этого поищите в возвращенной строке StandardOutput
"found no threats"
чтобы узнать, чист ли файл. Если этого нет, найдите строку, которая начинается с"Threat"
и прочтите, чтобы узнать, какой вирус был обнаружен.
Почему бы вам не выполнить следующие проверки только после того, как убедитесь, что процесс существует с 0, например,
if (process.ExitCode == 0)
{
process.Close();
process.Dispose();
if (File.Exists(path+filename) && !IsFileLocked(fileInfo) && Directory.Exists(cleanPath))
File.Move(path, cleanPath);
}
Я сомневаюсь, что процесс сканирования все еще изолирует файл, пока вы пытаетесь переместить.
ссылка: знаете, как проверить, заблокирован ли файл?
И, конечно же, вы должны обращаться с остальными условиями надлежащим образом...