在 c# 中获取进程的窗口列表,例如任务管理器

Getting window list for a process in c# like task manager

提问人:Michel Daudé 提问时间:11/12/2023 最后编辑:marc_sMichel Daudé 更新时间:11/12/2023 访问量:36

问:

我正在尝试获取任务管理器等进程的窗口列表,但我需要帮助...

样本:

任务管理中的窗口列表

您知道如何获得与任务管理器相同的窗口列表吗?

谢谢

在我的代码中,我尝试过这个,但结果与任务管理器不同。

将主句柄与 EnumChildWindows 一起使用:

var windowHelper = new WindowHandleInfo(process.MainWindowHandle);

IEnumerable<IntPtr> windows = windowHelper.GetAllChildHandles().
                                Where(p_Handle => windowHelper.getPidFromWindow(p_Handle) == process.Id && windowHelper.isWindowVisible(p_Handle));

foreach (var hWnd in windows)
{
    App.Log.Fatal($"Window visible : (Handle : {hWnd} - caption : {windowHelper.getWindowText(hWnd)})");
}

这种方法比任务管理器有更多的窗口。

结果:

2023-11-10 20:56:30,089 FATAL [5] CRMatrixAPI.Core.MainCore.OnCheckHMIResponding - Window visible : (Handle : 919276 - caption : )
2023-11-10 20:56:30,091 FATAL [5] CRMatrixAPI.Core.MainCore.OnCheckHMIResponding - Window visible : (Handle : 788236 - caption : Zone 1)
2023-11-10 20:56:30,092 FATAL [5] CRMatrixAPI.Core.MainCore.OnCheckHMIResponding - Window visible : (Handle : 789120 - caption : )
2023-11-10 20:56:30,092 FATAL [5] CRMatrixAPI.Core.MainCore.OnCheckHMIResponding - Window visible : (Handle : 919388 - caption : Zone 2)

对于文档,这是我的 WindowHandleInfo 类:

public class WindowHandleInfo
{
    private delegate bool EnumWindowProc(IntPtr hwnd, IntPtr lParam);

    [StructLayout(LayoutKind.Sequential)]
    public struct WINDOWINFO
    {
        public uint cbSize;
        public RECT rcWindow;
        public RECT rcClient;
        public uint dwStyle;
        public uint dwExStyle;
        public uint dwWindowStatus;
        public uint cxWindowBorders;
        public uint cyWindowBorders;
        public ushort atomWindowType;
        public ushort wCreatorVersion;

        public WINDOWINFO(Boolean? filler)
            : this()   // Allows automatic initialization of "cbSize" with "new WINDOWINFO(null/true/false)".
        {
            cbSize = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO)));
        }
    }

    [DllImport("user32")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool EnumChildWindows(IntPtr hWnd, EnumWindowProc callback, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

    [DllImport("user32.dll", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool IsHungAppWindow(IntPtr hwnd);

    [return: MarshalAs(UnmanagedType.Bool)]
    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool IsWindowVisible(IntPtr hWnd);

    [DllImport("user32.dll")]
    static extern bool CloseWindow(IntPtr hWnd);

    private IntPtr _MainHandle;

    public WindowHandleInfo(IntPtr handle)
    {
        this._MainHandle = handle;
    }

    public List<IntPtr> GetAllChildHandles()
    {
        List<IntPtr> childHandles = new List<IntPtr>();

        GCHandle gcChildhandlesList = GCHandle.Alloc(childHandles);
        IntPtr pointerChildHandlesList = GCHandle.ToIntPtr(gcChildhandlesList);

        try
        {
            EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
            EnumChildWindows(this._MainHandle, childProc, pointerChildHandlesList);
        }
        finally
        {
            gcChildhandlesList.Free();
        }

        return childHandles;
    }

    public int getPidFromWindow(IntPtr hWnd)
    {
        GetWindowThreadProcessId(hWnd, out int pid);
        return pid;
    }

    public bool windowIsAlive(IntPtr hWnd)
    {
        return !IsHungAppWindow(hWnd);
    }

    public string getWindowText(IntPtr hWnd)
    {
        const int nChars = 256;
        var buf = new StringBuilder(nChars);
        return GetWindowText(hWnd, buf, nChars) > 0 ? buf.ToString() : string.Empty;
    }

    public bool closeWindow(IntPtr hWnd)
    {
        // Close the window using API
        return CloseWindow(hWnd);
    }

    public bool IsMDI(IntPtr hwnd)
    {
        WINDOWINFO info = new WINDOWINFO();
        info.cbSize = (uint)Marshal.SizeOf(info);
        GetWindowInfo(hwnd, ref info);
        //0x00000040L is the style for WS_EX_MDICHILD
        return (info.dwExStyle & 0x00000040L) == 1;
    }

    public WINDOWINFO getWindowinfo(IntPtr hwnd)
    {
        WINDOWINFO info = new WINDOWINFO();
        info.cbSize = (uint)Marshal.SizeOf(info);
        GetWindowInfo(hwnd, ref info);
        return info;
    }

    public bool isWindowVisible(IntPtr hwnd)
    {
        return IsWindowVisible(hwnd);
    }

    private bool EnumWindow(IntPtr hWnd, IntPtr lParam)
    {
        GCHandle gcChildhandlesList = GCHandle.FromIntPtr(lParam);

        if (gcChildhandlesList == null || gcChildhandlesList.Target == null)
        {
            return false;
        }

        List<IntPtr> childHandles = gcChildhandlesList.Target as List<IntPtr>;
        childHandles.Add(hWnd);

        return true;
    }
}
c# 列表 任务管理器

评论

0赞 lidqy 11/12/2023
也许 TaskManager 只是显示进程的所有真子窗口的过滤子集?

答: 暂无答案