1

Windows Server 2008 R2 および Windows Server 2012 環境に展開されているクライアント用のカスタム プロセス監視アプリケーションをリファクタリングしています。

監視アプリケーションは、クラッシュした応答のないプロセス (タスク マネージャーで「応答なし」として識別される) を特定し、それらを強制終了して再起動する必要があります。監視対象のプロセスは、コンソールまたは Win32 ベースのアプリケーションのいずれかであり、主にコンソール ベースです。

Process.Respondingプロパティは、UI が応答しているかどうかを判断するため、この特定の場合には役に立ちません (このプロパティを更新するために、以下のような「フードの下で」同様のメソッドを使用する可能性があります)。

IsHungAppWindowメソッドも、コンソールベースのアプリケーションが次の基準を満たさないため、インポートされた場合は役に立ちません。

入力を待機しておらず、起動処理中ではなく、5 秒の内部タイムアウト期間内に PeekMessage を呼び出していない場合、アプリケーションは応答していないと見なされます。

WMI システム クラスを使用してプロセスを監視していた場合、WMI クラスのStatusプロパティは役に立ちません。Win32_Process

このプロパティは実装されておらず、このクラスのどのインスタンスにも設定されません。常に NULL です。

WMI クラスのExecutionStateプロパティWin32_Processも実装されていないように見えるため、役に立ちません。明示的には述べられていませんが、ローカル テストを実行した後、繰り返し返さNULLれ、サード パーティがこれを示しています。

プロセスが応答していないかどうかを合理的に判断するにはどうすればよいですか?

4

1 に答える 1

2

私が判断できる最善の答えと解決策は、Windows イベント ビューアー アプリケーション ログからイベントApplication Errorを監視することです。Application Hang

.NET 3.5 の時点で、イベント ログ全体の読み取りとフィルター処理を回避するために、便利なクラスが実装されました。代わりに、特定のイベントを監視できるようにするEventLogWatcherです。

EventIDでフィルタリングし、XPath クエリを使用する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]

于 2016-02-10T12:20:17.943 に答える