如何获取不响应前台应用程序的进程ID?

时间:2016-07-28 06:10:05

标签: c# windows winapi pinvoke

我有一个进程监视用户当前正在工作的窗口(GetForegroundWindow)。要通过HWND获取进程ID,请使用GetWindowThreadProcessId。但是,如果前台应用程序挂起,我将获得Desktop Window Manager - dwm.exe的进程ID。我可以确定是IsHungAppWindow挂起的app。 但是如何获得前景悬挂应用的真实流程ID?

2 个答案:

答案 0 :(得分:1)

使用C#,System.DiagnosticsSystem.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副本)。 Undocumented functions: HungWindowFromGhostWindow and GhostWindowFromHungWindow

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);
            }
        }
    }
}