WPF如何获取已打开应用列表并实现选中后跳转对应窗口
WPF 实现获取系统已打开应用列表并定位跳转窗口方案
核心实现原理
该功能依赖Windows系统原生API完成窗口枚举、状态获取和前置操作,不需要引入额外第三方库。
第一步:导入所需系统API
首先创建静态类封装Win32 API调用:
using System; using System.Runtime.InteropServices; using System.Text; public static class Win32Api { public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); public const uint WM_SYSCOMMAND = 0x0112; public const IntPtr SC_RESTORE = (IntPtr)0xF120; }
第二步:创建窗口信息实体类
用于绑定到WPF列表控件的数据源:
public class AppWindowInfo { public IntPtr WindowHandle { get; set; } public string WindowTitle { get; set; } public string ProcessName { get; set; } }
第三步:获取所有可见的已打开应用窗口列表
调用枚举API生成应用列表:
using System.Collections.Generic; using System.Diagnostics; public List<AppWindowInfo> GetAllOpenedApps() { var windowList = new List<AppWindowInfo>(); var currentProcessId = Process.GetCurrentProcess().Id; Win32Api.EnumWindows((hWnd, lParam) => { // 过滤不可见窗口 if (!Win32Api.IsWindowVisible(hWnd)) return true; // 获取窗口标题 var titleBuilder = new StringBuilder(256); Win32Api.GetWindowText(hWnd, titleBuilder, titleBuilder.Capacity); var windowTitle = titleBuilder.ToString().Trim(); if (string.IsNullOrEmpty(windowTitle)) return true; // 获取对应进程信息 Win32Api.GetWindowThreadProcessId(hWnd, out uint processId); // 过滤当前程序自身窗口,可根据需求去掉该判断 if (processId == currentProcessId) return true; using var process = Process.GetProcessById((int)processId); windowList.Add(new AppWindowInfo { WindowHandle = hWnd, WindowTitle = windowTitle, ProcessName = process.ProcessName }); return true; }, IntPtr.Zero); return windowList; }
获取到列表后直接绑定到WPF的ListBox/DataGrid等列表控件即可。
第四步:选中应用后定位跳转窗口
在列表的选中事件中添加如下逻辑:
private void AppList_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) { if (e.AddedItems.Count == 0) return; var selectedApp = e.AddedItems[0] as AppWindowInfo; if (selectedApp == null) return; // 如果窗口处于最小化状态,先还原窗口 Win32Api.SendMessage(selectedApp.WindowHandle, Win32Api.WM_SYSCOMMAND, Win32Api.SC_RESTORE, IntPtr.Zero); // 将目标窗口前置到桌面最顶层 Win32Api.SetForegroundWindow(selectedApp.WindowHandle); }
注意事项
- 若要过滤系统内置窗口、后台工具窗口,可额外添加窗口样式判断逻辑,调用
GetWindowLongPtr获取窗口样式过滤即可 - 枚举窗口时默认已过滤无标题的系统后台窗口,可根据业务需求调整过滤规则
- 程序需要正常的用户权限即可运行,不需要管理员权限
内容的提问来源于stack exchange,提问作者Silent Programmer
相关产品推荐
相关产品推荐

