我有一个进程监视用户当前正在工作的窗口(GetForegroundWindow)。要通过HWND获取进程ID,请使用GetWindowThreadProcessId。但是,如果前台应用程序挂起,我将获得Desktop Window Manager - dwm.exe的进程ID。我可以确定是IsHungAppWindow挂起的app。 但是如何获得前景悬挂应用的真实流程ID?
答案 0 :(得分:1)
使用C#,System.Diagnostics
和System.Linq
您可以这样做:
List<IntPtr> handles = System.Diagnostics.Process.GetProcesses()
.Where(x => !x.Responding)
.Select(x => x.MainWindowHandle).ToList();
返回没有响应的进程的句柄。
答案 1 :(得分:0)
我们可以使用来自user32.dll HungWindowFromGhostWindow的未记录方法从ghost句柄获取真正的窗口句柄(如果窗口挂起,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);
}
}
}
}