[英]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 Error
和Application Hang
事件。
從.NET 3.5開始,實現了一個方便的類,以避免讀取和過濾整個事件日志: EventLogWatcher允許監視特定事件。
這是一個非常基本的示例,使用XPath查詢按EventID
, Level
和ApplicationName
進行過濾:
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.