如何获取没有响应的前台应用程序的进程ID?
How to get the process Id of not responding foreground app?
我有一个监控用户当前正在工作的 window 的进程(GetForegroundWindow). To get process ID by HWND I use GetWindowThreadProcessId. But, if foreground app is hung, I will get the process Id of Desktop Window Manager - dwm.exe. I can determine is app hung by IsHungAppWindow。但是如何获取前台挂起应用程序的真实进程 ID?
使用 C#,System.Diagnostics
和 System.Linq
你可以这样做:
List<IntPtr> handles = System.Diagnostics.Process.GetProcesses()
.Where(x => !x.Responding)
.Select(x => x.MainWindowHandle).ToList();
哪个 returns 没有响应的进程句柄。
我们可以使用 user32.dll HungWindowFromGhostWindow 中未记录的方法从 ghost 句柄中获取真正的 window 句柄(如果 windows 挂起,dwm 会创建其 ghost 副本)。
namespace HungProcessName
{
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;
using System;
class Program
{
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern IntPtr GhostWindowFromHungWindow(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern IntPtr HungWindowFromGhostWindow(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern bool IsHungAppWindow(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hwnd, out uint procId);
static void Main(string[] args)
{
while (true)
{
var hwnd = GetForegroundWindow();
Console.WriteLine("Foreground window: {0}", hwnd);
if (IsHungAppWindow(hwnd))
{
var hwndReal = HungWindowFromGhostWindow(hwnd);
uint procId = 0;
GetWindowThreadProcessId(hwndReal, out procId);
if (procId > 0)
{
Process proc = null;
try { proc = Process.GetProcessById((int)procId); }
catch (Exception ex)
{
Console.WriteLine("Could not get proces with Id '{0}': {1}", procId, ex);
}
if (proc != null)
{
Console.WriteLine("Ghost hwnd: {0}, Real hwnd: {1}. ProcessId: {2}, Proccess name: {3}",
hwnd, hwndReal, procId, proc.ProcessName);
}
}
}
Thread.Sleep(100);
}
}
}
}
我有一个监控用户当前正在工作的 window 的进程(GetForegroundWindow). To get process ID by HWND I use GetWindowThreadProcessId. But, if foreground app is hung, I will get the process Id of Desktop Window Manager - dwm.exe. I can determine is app hung by IsHungAppWindow。但是如何获取前台挂起应用程序的真实进程 ID?
使用 C#,System.Diagnostics
和 System.Linq
你可以这样做:
List<IntPtr> handles = System.Diagnostics.Process.GetProcesses()
.Where(x => !x.Responding)
.Select(x => x.MainWindowHandle).ToList();
哪个 returns 没有响应的进程句柄。
我们可以使用 user32.dll HungWindowFromGhostWindow 中未记录的方法从 ghost 句柄中获取真正的 window 句柄(如果 windows 挂起,dwm 会创建其 ghost 副本)。
namespace HungProcessName
{
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;
using System;
class Program
{
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern IntPtr GhostWindowFromHungWindow(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern IntPtr HungWindowFromGhostWindow(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern bool IsHungAppWindow(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hwnd, out uint procId);
static void Main(string[] args)
{
while (true)
{
var hwnd = GetForegroundWindow();
Console.WriteLine("Foreground window: {0}", hwnd);
if (IsHungAppWindow(hwnd))
{
var hwndReal = HungWindowFromGhostWindow(hwnd);
uint procId = 0;
GetWindowThreadProcessId(hwndReal, out procId);
if (procId > 0)
{
Process proc = null;
try { proc = Process.GetProcessById((int)procId); }
catch (Exception ex)
{
Console.WriteLine("Could not get proces with Id '{0}': {1}", procId, ex);
}
if (proc != null)
{
Console.WriteLine("Ghost hwnd: {0}, Real hwnd: {1}. ProcessId: {2}, Proccess name: {3}",
hwnd, hwndReal, procId, proc.ProcessName);
}
}
}
Thread.Sleep(100);
}
}
}
}