如何识别无响应的进程

本文关键字:响应 进程 识别 何识别 | 更新日期: 2023-09-27 18:34:05

我正在为部署在Windows Server 2008 R2和Windows Server 2012环境中的客户端重构自定义进程监视应用程序。

监视应用程序需要识别崩溃的、无响应的进程(在任务管理器中标识为"未响应"(,强制终止它们并重新启动。监视的进程可以是控制台或基于 Win32 的应用程序,主要基于控制台。

Process.Response 属性在此特定情况下没有用处,因为它确定 UI 是否正在响应(可能使用与下面的方法类似的"幕后"方法来更新此属性(。

如果导入了IsHungAppWindow方法,则该方法也没有用,因为基于控制台的应用程序不满足以下条件:

如果应用程序未等待输入、未处于启动处理中,并且未在 5 秒的内部超时期限内调用 PeekMessage,则认为该应用程序没有响应。

Win32_Process WMI 类的 Status 属性在我使用 WMI 系统类监视进程时没有用,因为:

此属性未实现,并且不会为此类的任何实例填充。它始终为空。

Win32_Process WMI 类的 ExecutionState 属性没有用,因为它似乎也没有实现。虽然没有明确说明,但在运行本地测试后,它会反复返回NULL并且第三方会指示这一点。

如何合理地确定进程是否无响应?

如何识别无响应的进程

我可以确定的最佳答案和解决方案是监视 Windows 事件查看器应用程序日志中的Application ErrorApplication Hang事件。

从.NET 3.5开始,实现了一个方便的类来避免读取和过滤整个事件日志:EventLogWatcher允许监视特定事件。

下面是一个非常基本的示例,使用 XPath 查询按EventIDLevelApplicationName进行筛选:

using System.Globalization;
using System.Diagnostics.Eventing.Reader;
EventLogQuery filter = new EventLogQuery("Application", PathType.LogName, "Event[System[Level=2 and (EventID = 1000 or EventID = 1002)] and EventData[Data[1] = '"example.exe'"]]")
EventLogWatcher watcher = new EventLogWatcher(filter);
watcher.EventRecordWritten += Watcher_ApplicationError; // Register our handler
watcher.Enabled = true; // Start delivering events to the handler
private void Watcher_ApplicationError(object sender, EventRecordWrittenEventArgs e) 
{
     String rawId = e.EventRecord.Properties[8].Value.ToString(); // Faulting process id
     Int32 id = -1;
     if (!Int32.TryParse(rawId, out id)) // If not integer, possibly hexadecimal
     {
         if (!Int32.TryParse(rawId, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out id)
             return; // Unable to read the process id successfully
     }
     Process unresponsive = Process.GetProcessById(id); // Get the unresponsive process
     unresponsive.Kill(); // Kill it
}

这可以很容易地扩展为按完全限定的、错误的应用程序执行路径Properties[10]进行过滤。