【问题标题】:How to identify an unresponsive process?如何识别无响应的进程?
【发布时间】:2016-02-10 12:20:17
【问题描述】:

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

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

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

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

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

如果我使用 WMI 系统类监视进程,Win32_Process WMI 类的 Status 属性将毫无用处,因为:

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

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

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

【问题讨论】:

    标签: c# process wmi system.diagnostics process-monitoring


    【解决方案1】:

    我能确定的最佳答案和解决方案是监视 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]进行过滤。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多