获取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
获取Windows正在运行的窗口进程的更多相关文章
- [Android Pro] 获取手机已经安装的应用 和 获取当前正在运行的所有进程(一个uid对应多个pid)
1: 获取PackageManager 获取全部静态已安装的应用: PackageManager pm = getPackageManager(); List<PackageInfo> i ...
- C#获取运行程序的进程ID
C#获取运行程序的进程ID [DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern int G ...
- 【linux】linux下准确查询正在tomcat下运行的java进程。准确获取正在运行的java进程的PID
准确获取定位到tomcat下正在运行的java进程的PID命令: ps -ef|grep java | grep catalina | awk '{print $2}' 准确定位到tomcat下正在运 ...
- 电脑出现“损坏的图像”窗口提示dll没有被指定在Windows上运行如何解决
电脑中出现了无法运行应用程序的情况,弹出一个“***.exe - 损坏的图像”的窗口,上面提示“***.dll没有被指定在Windows上运行……”,如果我们遇到这样的问题,应该要如何解决呢? 1.我 ...
- 黄聪:使用srvany.exe将任何程序作为Windows服务运行
srvany.exe是什么? srvany.exe是Microsoft Windows Resource Kits工具集的一个实用的小工具,用于将任何EXE程序作为Windows服务运行.也就是说sr ...
- 使用srvany.exe将任何程序作为Windows服务运行
使用srvany.exe将任何程序作为Windows服务运行 2011 年 3 月 7 日 !本文可能 超过1年没有更新,今后内容也许不会被维护或者支持,部分内容可能具有时效性,涉及技术细节或者软件使 ...
- .NET Worker Service 作为 Windows 服务运行及优雅退出改进
上一篇文章我们了解了如何为 Worker Service 添加 Serilog 日志记录,今天我接着介绍一下如何将 Worker Service 作为 Windows 服务运行. 我曾经在前面一篇文章 ...
- 通过PowerShell获取Windows系统密码Hash
当你拿到了系统控制权之后如何才能更长的时间内控制已经拿到这台机器呢?作为白帽子,已经在对手防线上撕开一个口子,如果你需要进一步扩大战果,你首先需要做的就是潜伏下来,收集更多的信息便于你判断,便于有更大 ...
- windows使用命令行杀进程
在windows有时使用任务管理器杀进程,一直杀不掉: 这个时候,可以使用命令行: 先使用tasklist 命令查看当前系统中的进程列表,然后针对你要杀的进程使用taskkill命令 如要杀nginx ...
随机推荐
- springboot执行流程
构造方法初始化,创建一个新的实例,这个应用程序的上下文要从指定的来源加载bean public SpringApplication(ResourceLoaderresourceLoader,Class ...
- 【Github】 Github修改仓库的基本信息
前言 我们通常在刚开始了解学习使用github时,一般都是测试的使用,有时我们向里面添加了一些代买,如果想要修改信息并且是删除仓库重新创建提交,可以采用下面方法修改仓库信息,名称.描述等. 修改仓库描 ...
- 编程技巧│提高 Javascript 代码效率的技巧
目录 一.变量声明 二.三元运算符 三.解构赋值 四.解构交换 五.箭头函数 六.字符串模版 七.多值匹配 八.ES6对象简写 九.字符串转数字 十.次方相乘 十一.数组合并 十二.查找数组最大值最小 ...
- 全网求解,用Python处理一个基础题目
昨天在群里看见一个Python的问题,趁着今天有那么一点点时间,就想把这个题目分享出来,让大家一起解决.毕竟三个臭皮匠,赛过诸葛亮.原始数据如下: 1 origin_lst = [0, 0, 1, 2 ...
- go-zero微服务实战系列(八、如何处理每秒上万次的下单请求)
在前几篇的文章中,我们花了很大的篇幅介绍如何利用缓存优化系统的读性能,究其原因在于我们的产品大多是一个读多写少的场景,尤其是在产品的初期,可能多数的用户只是过来查看商品,真正下单的用户非常少.但随着业 ...
- Java中Double类型数据比较大小
方法一:转成字符串之后比较 如果要比较的两个double数据的字符串精度相等,可以将数据转换成string然后借助string的equals方法来间接实现比较两个double数据是否相等.注意这种方法 ...
- 机器学习基础:用 Lasso 做特征选择
大家入门机器学习第一个接触的模型应该是简单线性回归,但是在学Lasso时往往一带而过.其实 Lasso 回归也是机器学习模型中的常青树,在工业界应用十分广泛.在很多项目,尤其是特征选择中都会见到他的影 ...
- 跨平台(32bit和64bit)的 printf 格式符 %lld 输出64位的解决方式
问题描述 在 C/C++ 开发中,使用 printf 打印 64 位变量比较常用,通常在 32 位系统中使用 %lld 输出 64 位的变量,而在 64 位系统中则使用 %ld: 如果在 32 位系统 ...
- P2599 [ZJOI2009]取石子游戏 做题感想
题目链接 前言 发现自己三岁时的题目都不会做. 我发现我真的是菜得真实. 正文 神仙构造,分讨题. 不敢说有构造,但是分讨我只服这道题. 看上去像是一个类似 \(Nim\) 游戏的变种,经过不断猜测结 ...
- 如果一个promise永不resolve,会内存泄漏吗
答:跟内存泄漏没有直接关系gc的策略不会改变,如果该promise没有被人引用,就会被gc掉.如果仍被引用,就不会被gc掉.即使一个promise,resolve或者reject了,但是它还被人引用, ...