主要是获取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

获取Windows正在运行的窗口进程的更多相关文章

  1. [Android Pro] 获取手机已经安装的应用 和 获取当前正在运行的所有进程(一个uid对应多个pid)

    1: 获取PackageManager 获取全部静态已安装的应用: PackageManager pm = getPackageManager(); List<PackageInfo> i ...

  2. C#获取运行程序的进程ID

    C#获取运行程序的进程ID [DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern int G ...

  3. 【linux】linux下准确查询正在tomcat下运行的java进程。准确获取正在运行的java进程的PID

    准确获取定位到tomcat下正在运行的java进程的PID命令: ps -ef|grep java | grep catalina | awk '{print $2}' 准确定位到tomcat下正在运 ...

  4. 电脑出现“损坏的图像”窗口提示dll没有被指定在Windows上运行如何解决

    电脑中出现了无法运行应用程序的情况,弹出一个“***.exe - 损坏的图像”的窗口,上面提示“***.dll没有被指定在Windows上运行……”,如果我们遇到这样的问题,应该要如何解决呢? 1.我 ...

  5. 黄聪:使用srvany.exe将任何程序作为Windows服务运行

    srvany.exe是什么? srvany.exe是Microsoft Windows Resource Kits工具集的一个实用的小工具,用于将任何EXE程序作为Windows服务运行.也就是说sr ...

  6. 使用srvany.exe将任何程序作为Windows服务运行

    使用srvany.exe将任何程序作为Windows服务运行 2011 年 3 月 7 日 !本文可能 超过1年没有更新,今后内容也许不会被维护或者支持,部分内容可能具有时效性,涉及技术细节或者软件使 ...

  7. .NET Worker Service 作为 Windows 服务运行及优雅退出改进

    上一篇文章我们了解了如何为 Worker Service 添加 Serilog 日志记录,今天我接着介绍一下如何将 Worker Service 作为 Windows 服务运行. 我曾经在前面一篇文章 ...

  8. 通过PowerShell获取Windows系统密码Hash

    当你拿到了系统控制权之后如何才能更长的时间内控制已经拿到这台机器呢?作为白帽子,已经在对手防线上撕开一个口子,如果你需要进一步扩大战果,你首先需要做的就是潜伏下来,收集更多的信息便于你判断,便于有更大 ...

  9. windows使用命令行杀进程

    在windows有时使用任务管理器杀进程,一直杀不掉: 这个时候,可以使用命令行: 先使用tasklist 命令查看当前系统中的进程列表,然后针对你要杀的进程使用taskkill命令 如要杀nginx ...

随机推荐

  1. Docker容器固定ip

    Docker容器固定IP 必须停止docker服务才能创建网桥 查看docker服务状态 停止docker服务 启动docker服务 [root@docker Tools]# systemctl st ...

  2. 一文搞懂Kafka的基本原理及使用

    Kafka的基本原理及使用 一.基本概念及原理 1.Kafka特点 Kafka 是一个分布式的流式平台,流式平台包括以下三个特点: 发布和订阅消息(流),类似于一个消息队列或企业消息系统 持久化收到的 ...

  3. BUUCTF-被偷走的文件

    被偷走的文件 这题刚开始还以为是单纯的流量题,看流量半天也没发现什么异常. 因为是文件传输过程的,所以我们看到ftp的流量就过滤下看看即可. 在第三个包发现flag.rar存在. 一开始我觉得没啥,后 ...

  4. SAP APO - 简介

    SAP高级计划和优化(SAP APO)是SAP SCM中的关键模块之一,在供应链流程中控制供应网络计划,备件计划,TP / VS和需求计划. 它可以帮助组织在动态环境中管理其供应链流程. SAP AP ...

  5. 机械硬盘和ssd固态硬盘的原理对比分析

    固态硬盘和机械硬盘的区别 机械硬盘 磁头是不是直接和盘片接触的呢 磁盘中有几个盘片 机械硬盘的工作原理 固态硬盘的寻址方式 SMR叠瓦式真的比PMR优秀吗 固态硬盘 主控芯片 闪存颗粒 缓存单元 固态 ...

  6. 获取请求体数据 POST

    POST获取请求体 请求体中封装了 POST请求的请求参数 获取流对象 再从流对象中那数据 一种字节流 一种字符流 BufferedReader getReader()获取字符输入流 只能操作字符 S ...

  7. Windows启动谷歌浏览器Chrome失败(应用程序无法启动,因为应用程序的并行配置不正确)解决方法

    目录 一.系统环境 二.问题描述 三.解决方法 一.系统环境 Windows版本 系统类型 浏览器Chrome版本 Windows 10 专业版 64 位操作系统, 基于 x64 的处理器 版本 10 ...

  8. Linux 目录挂载服务

    Linux 服务器挂载文件目录通常有三种形式,手动挂载.自动挂载.Autofs 自动挂载,下面对这三个挂载做一下介绍,接受一下这三个区别以及使用场景: 准备服务器和客户端: server 192.16 ...

  9. Tapdata 实时数据融合平台解决方案(四):技术选型

    作者介绍:TJ,唐建法,Tapdata 钛铂数据CTO,MongoDB中文社区主席,原MongoDB大中华区首席架构师,极客时间MongoDB视频课程讲师. 常见搭建数据中台的技术产品 数据中台包括: ...

  10. java,捕获和抛出异常

    package Exrro; public class Test { //ctrl + alt + T快速生成异常捕捉 public static void main(String[] args) { ...