最終的には、プロセスの GDI オブジェクト数が既定の 10,000 の制限に近づいた場合に警告する自動アラートを設定する方法を探しています。弊社で使用しているソフトウェアに既知の問題があり、explorer.exe でカウントが増加して警告なしにクラッシュします。どうやら、ソフトウェアの最新バージョンではこの問題が修正されているようですが、制御できない理由でアップグレードできません。私のアイデアは、GDI 数が 10,000 の制限に近づいたときにアラートをポップアップ表示するバックグラウンド プログラム/スクリプトを作成することです。ただし、GDI 数を表示できる唯一の方法は、タスク マネージャーまたは Process Explorer の GUI を使用する方法のようです。何らかの方法でそれをテキスト ファイルに自動的にダンプできれば準備は整いますが、それが可能かどうかはわかりません。
GDIView ソフトウェアを試してみましたが、弊社のウイルス対策ソフトウェアがこれにフラグを立てており、私の管理外です。
sysinterals をダウンロードしましたが、Process Explorer で取得できる GDI カウントをコマンド ライン ツールでエコーする方法がわかりません。tasklist も試しましたが、同様に GDI カウントを取得する方法が見つかりません。
参考までに、私は Windows 10 マシンを使用しています。Linux サブシステムも有効にしており、それを介して Ubuntu を実行する機能があります。役に立つ場合は、バッチまたは Python で何かを実行することもできますが、PowerShell ではスクリプトの実行がブロックされているようです (ただし、これを回避できる可能性があります)。
答え1
私は、Rudolfが作成したプロセスごとのカウントを表示するPowershellコードの小さなセクションを見つけました。Powershell でプロセスごとの GDI オブジェクト数を取得する
"Number of GUI handles per process"
$sig = @'
[DllImport("User32.dll")]
public static extern int GetGuiResources(IntPtr hProcess, int uiFlags);
'@
Add-Type -MemberDefinition $sig -name NativeMethods -namespace Win32
$processes = [System.Diagnostics.Process]::GetProcesses()
[int]$gdiHandleCount = 0
ForEach ($p in $processes)
{
try{
$gdiHandles = [Win32.NativeMethods]::GetGuiResources($p.Handle, 0)
$gdiHandleCount += $gdiHandles
$p.Name + " : " + $gdiHandles.ToString()
}
catch {
#"Error accessing " + $p.Name
}
}
"Total number of GDI handles " + $gdiHandleCount.ToString()
try ... Catchステートメント内のコマンドを変更して、if文エクスプローラー名と一致し、メッセージ ボックスを表示します。