我有一个Windows服务,该服务监视文件夹中的新文件并运行一个过程。但是,每次我将文件放入受监视的文件夹时,该服务都会崩溃。这是我收到的异常:
应用程序:框架版本:v4.0.30319说明:该过程由于未处理的异常而被终止。异常信息:System.IO.IOException堆栈:位于System.IO ._ Error.WinIOError(Int32,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()
{
}
我怀疑在某些情况下该进程仍对文件具有锁定。只是想知道,为什么不打电话:
process.Close(); // Frees all the resources that are associated with this component
在WaitForExit()之后。
为什么您在确保进程存在0之后就不进行以下检查,像这样,
if (process.ExitCode == 0)
{
process.Close();
process.Dispose();
if (File.Exists(path+filename) && !IsFileLocked(fileInfo) && Directory.Exists(cleanPath))
File.Move(path, cleanPath);
}
我怀疑在尝试移动时扫描过程是否仍在隔离文件。
参考:know how to check a file is locked?
当然,您应该适当地处理else条件...
我在创建进程之前添加了Thread.Sleep(5000)。效果很好,但扫描每个文件的时间为5秒。而且,正如人们所说的那样,这感觉有点骇人听闻。
可能是另一个进程,例如您正在手动启动的扫描仪的另一个实例,在您尝试移动文件时仍对该文件持有了锁定?
您应该使用Process Monitor查看哪些进程正在访问文件。
无论如何,您不扫描新文件,而是始终扫描整个文件夹L:\ Test。那是你的意图吗?
[使用MpCmdRun时似乎需要两个技巧:
在调用-DisableRemediation
时将MpCmdRun
包括到参数列表中。这将导致进程运行非常快,并通过StandardOutput
将结果报告回来。
忽略返回的退出代码。而是在返回的StandardOutput字符串中查找"found no threats"
,以了解文件是否干净。如果不存在,请查找以"Threat"
开头的行,然后阅读以查看发现了什么病毒。