获取Windows正在运行的窗口进程

博客 动态
0 112
羽尘
羽尘 2022-08-28 17:03:47
悬赏:0 积分 收藏

获取Windows正在运行的窗口进程

主要是获取Alt+Tab中展示的窗口

原理主要是获取窗口的样式来判断是否会在Alt+Tab中显示

具体代码如下

/// <summary>        /// Alt+Tab 应用        /// </summary>        /// <param name="hWnd"></param>        /// <returns></returns>        public static bool IsAltTabWindow(IntPtr hWnd)        {            // The window must be visible            if (!IsWindowVisible(hWnd))                return false;            // The window must be a root owner            if (GetAncestor(hWnd, GA_ROOTOWNER) != hWnd)                return false;            // The window must not be cloaked by the shell            DwmGetWindowAttribute(hWnd, DwmWindowAttribute.DWMWA_CLOAKED, out int cloaked, sizeof(uint));            if (cloaked == DWM_CLOAKED_SHELL)                return false;            // The window must not have the extended style WS_EX_TOOLWINDOW            int style = Utils.Win32Api.GetWindowLong(hWnd, GWL_EXSTYLE);            if ((style & WS_EX_TOOLWINDOW) != 0)                return false;            return true;        } [DllImport("User32.dll", CharSet = CharSet.Auto)]        public static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll")]        public static extern IntPtr GetAncestor(IntPtr hWnd, uint gaFlags); [DllImport("dwmapi.dll")]        public static extern int DwmGetWindowAttribute(IntPtr hwnd, DwmWindowAttribute dwAttribute, out int attrValue, int cbAttribute);const uint DWM_CLOAKED_SHELL = 0x00000002;        const uint GA_ROOTOWNER = 3;        const uint WS_EX_TOPMOST = 0x00000008;[Flags]    public enum DwmWindowAttribute : uint    {        DWMWA_NCRENDERING_ENABLED = 1,        DWMWA_NCRENDERING_POLICY,        DWMWA_TRANSITIONS_FORCEDISABLED,        DWMWA_ALLOW_NCPAINT,        DWMWA_CAPTION_BUTTON_BOUNDS,        DWMWA_NONCLIENT_RTL_LAYOUT,        DWMWA_FORCE_ICONIC_REPRESENTATION,        DWMWA_FLIP3D_POLICY,        DWMWA_EXTENDED_FRAME_BOUNDS,        DWMWA_HAS_ICONIC_BITMAP,        DWMWA_DISALLOW_PEEK,        DWMWA_EXCLUDED_FROM_PEEK,        DWMWA_CLOAK,        DWMWA_CLOAKED,        DWMWA_FREEZE_REPRESENTATION,        DWMWA_LAST    } /// <summary>        /// 获取窗体句柄        /// </summary>        /// <param name="hwnd"></param>        /// <param name="nIndex"></param>        /// <returns></returns>        [DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]        public static extern int GetWindowLong(IntPtr hwnd, int nIndex);const int GWL_EXSTYLE = -20;//得到扩展的窗口风格    public const int WS_EX_TOOLWINDOW = 0x00000080;

  以上方式对于全屏的UWP窗口时无法获取得到的,因此需要引入以下方式获取全屏UWP窗口

/// <summary>        /// 全屏的UWP应用        /// </summary>        /// <param name="hWnd"></param>        /// <returns></returns>        public  static  bool IsFullScreenUwpWindows(IntPtr hWnd)        {            // Get the extended style of the window            var style = GetWindowLong(hWnd, GWL_EXSTYLE);            // The window must have the extended style WS_EX_TOPMOST            if ((style & WS_EX_TOPMOST) == 0)                return false;            // The window must not have the extended style WS_EX_NOACTIVATE            if ((style & WS_EX_NOACTIVATE) != 0)                return false;            // The window must not have the extended style WS_EX_TOOLWINDOW            if ((style & WS_EX_TOOLWINDOW) != 0)                return false;            return true;        }public const int WS_EX_NOACTIVATE = 0x08000000;

然后通过枚举窗口的方式就可以获取到所有窗口了

/// <summary>        /// 枚举窗体的回调        /// </summary>        /// <param name="hwnd"></param>        /// <param name="lParam"></param>        /// <returns></returns>        public delegate bool EnumWindowsCallBack(IntPtr hwnd, IntPtr lParam);        /// <summary>        /// 枚举出窗体        /// </summary>        /// <param name="x"></param>        /// <param name="y"></param>        /// <returns></returns>        [DllImport("user32")]        public static extern int EnumWindows(EnumWindowsCallBack x, IntPtr y); /// <summary>        /// 枚举子窗口        /// </summary>        /// <param name="hWndParent"></param>        /// <param name="x"></param>        /// <param name="y"></param>        /// <returns></returns>        [DllImport("user32")]        public static extern int EnumChildWindows(IntPtr hWndParent, EnumWindowsCallBack x, IntPtr y); List<KeyValuePair<IntPtr, string>> handles = new List<KeyValuePair<IntPtr, string>>();            EnumWindows((hWnd, lPam) =>            {                if (!IsAltTabWindow(hWnd)) return true;//继续枚举                var title = GetWindowTitle(hWnd);                handles.Add(new KeyValuePair<IntPtr, string>(hWnd, title));                return true;//继续枚举            }, IntPtr.Zero);            EnumChildWindows(GetDesktopWindow(), (hWnd, lPam) =>            {                if (handles.Any(kv => kv.Key == hWnd)||!IsFullScreenUwpWindows(hWnd)) return true;//继续枚举                var title = GetWindowTitle(hWnd);                handles.Add(new KeyValuePair<IntPtr, string>(hWnd, title));                return true;//继续枚举            }, IntPtr.Zero);[DllImport("user32.dll")]        public static extern IntPtr GetDesktopWindow();/// <summary>        /// 获取窗体的名称        /// </summary>        /// <param name="hWnd"></param>        /// <param name="lpString"></param>        /// <param name="nMaxCount"></param>        /// <returns></returns>        [DllImport("user32.dll")]        public static extern int GetWindowTextW(IntPtr hWnd, IntPtr lpString, int nMaxCount);/// <summary>        /// 默认获取字符串的长度        /// </summary>        private const int NumChars = 256;        public static string GetWindowTitle(IntPtr hwnd)        {            IntPtr intPtr = Marshal.AllocHGlobal(NumChars);            Utils.Win32Api.GetWindowTextW(hwnd, intPtr, 100);            var s = Marshal.PtrToStringUni(intPtr);            Marshal.FreeHGlobal(intPtr);            return s;        }

以上代码需要做调整才能运行起来,有空我补上完整代码

参考:https://stackoverflow.com/questions/72069771/show-a-list-of-all-alttab-windows-even-full-screen-uwp-windows-and-retrieve

 

posted @ 2022-08-28 16:44 黄高林 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    羽尘

    羽尘 (王者 段位)

    2335 积分 (2)粉丝 (11)源码

     

    温馨提示

    亦奇源码

    最新会员