簡體   English   中英

如何識別無響應的過程?

[英]How to identify an unresponsive process?

我正在為在Windows Server 2008 R2和Windows Server 2012環境中部署的客戶端重構自定義過程監視應用程序。

監視應用程序需要識別崩潰的無響應進程(在任務管理器中標識為“無響應”),強行殺死它們並重新啟動。 監視的進程可以是基於控制台的應用程序,也可以是基於Win32的應用程序,主要是基於控制台的應用程序。

在此特定情況下, Process.Responding屬性沒有用,因為它確定UI是否正在響應(可能使用與下面類似的“幕后”方法來更新此屬性)。

如果導入了IsHungAppWindow方法,因為基於控制台的應用程序不滿足以下條件,則該方法也沒有用:

如果應用程序未等待輸入,未處於啟動處理中且未在5秒鍾的內部超時時間內調用PeekMessage,則認為該應用程序沒有響應。

如果我監視使用WMI系統類的進程,則Win32_Process WMI類的Status屬性沒有用:

未實現此屬性,並且不會為此類的任何實例填充此屬性。 始終為NULL。

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]進行過濾。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM