3

我有一个 Windows 服务,它监视文件夹中的新文件并运行一个进程。但是,每次我将文件放入受监控的文件夹时,该服务都会崩溃。这是我收到的异常:

应用程序:框架版本: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

5 回答 5

1

我怀疑在某些情况下该过程仍然锁定文件。只是想知道,你为什么不打电话:

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

在 WaitForExit() 之后。

于 2011-08-31T17:34:58.350 回答
1

可能是另一个进程,例如您手动启动的另一个扫描仪实例,在您尝试移动文件时仍然锁定文件?

您应该使用进程监视器来查看哪些进程正在访问该文件。

无论如何,您不会扫描新文件,而是始终扫描整个文件夹 L:\Test。这是你的意图吗?

于 2011-09-02T13:44:49.967 回答
0

为什么不在确保进程以 0 存在之后立即进行以下检查,就像这样,

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

我怀疑在您尝试移动时扫描过程是否仍在隔离文件。

参考:知道如何检查文件是否被锁定?

当然,你应该适当地处理 else 条件......

于 2011-08-31T18:08:11.797 回答
0

我在创建进程之前添加了 Thread.Sleep(5000) 。这很好用,但它会在 5 秒内扫描每个文件。而且,正如人们所说的那样,这感觉有点骇人听闻。

于 2011-09-02T13:38:29.653 回答
0

使用 MpCmdRun 时似乎需要两个技巧:

  1. 调用时包括-DisableRemediation在参数列表中MpCmdRun。这会导致该过程非常快速地运行并通过StandardOutput.

  2. 忽略返回的退出代码。相反,查看返回的 StandardOutput 字符串"found no threats"以了解文件是否干净。如果不存在,请查找以开头的行"Threat"并阅读它以查看发现了什么病毒。

于 2020-02-26T23:26:14.643 回答