You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 00:09:01