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

如何用Java获取Windows任务管理器中显示的当前运行应用名称?

Java获取Windows任务管理器中显示的应用名称问题

我希望用Java获取Windows任务管理器中显示的当前运行应用名称(如IntelliJ IDEA、Google Chrome),但现有代码无法实现预期效果。

现有代码

import com.sun.jna.Native;
import com.sun.jna.platform.win32.*;
import com.sun.jna.ptr.IntByReference;

public class AppList {

    public static void main(String[] args) {

        // 打印活动窗口标题(不符合需求)
        User32 user32 = User32.INSTANCE;
        WinDef.HWND hwnd = user32.GetForegroundWindow();
        char[] title = new char[1024];
        user32.GetWindowText(hwnd, title, title.length);
        System.out.println("Active window: " + String.valueOf(title));
        // 输出:"Active window: Project4 - AppList.java"

        // 打印活动应用路径并格式化(仍不符合需求)
        IntByReference processId = new IntByReference();
        int id = user32.GetWindowThreadProcessId(hwnd, processId);
        WinNT.HANDLE processHandle = Kernel32.INSTANCE.OpenProcess(
                WinNT.PROCESS_QUERY_INFORMATION | WinNT.PROCESS_VM_READ, false, processId.getValue());
        char[] exePath = new char[1024];
        Psapi.INSTANCE.GetModuleFileNameExW(processHandle, null, exePath, exePath.length);
        String exePathStr = Native.toString(exePath);
        System.out.println(exePathStr);
        // 输出:"C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2023.3.2\bin\idea64.exe"

        // 格式化处理
        String activeAppName = exePathStr.substring(exePathStr.lastIndexOf("\\") + 1)
                .replace(".exe", "").toLowerCase();
        char firstChar = Character.toUpperCase(activeAppName.charAt(0));
        activeAppName = firstChar + activeAppName.substring(1);

        System.out.println(activeAppName);
        Kernel32.INSTANCE.CloseHandle(processHandle);
        // 得到"Idea64"而非"IntelliJ IDEA"
        // 得到"Chrome"而非"Google Chrome"
        // 得到"Applicationframehost"而非"设置"
        // 任务管理器相关完全无法正常工作
    }
}

现有代码的问题

  • 第一种方法获取活动窗口标题,仅部分场景可用,多数情况不符合需求;
  • 第二种方法获取应用路径并格式化,仅部分场景(如Spotify)可用,多数情况得到奇怪名称或完全失效。

我已花费数小时搜索和咨询AI,仅找到这两种方法,未能解决问题。


解决方案

核心思路

任务管理器显示的名称来源分两类:

  1. 传统Win32应用:名称来自可执行文件的文件描述(对应文件属性“详细信息”中的描述)
  2. UWP应用(如“设置”、应用商店应用):名称来自应用包的显示名称

修正后的代码

import com.sun.jna.Native;
import com.sun.jna.platform.win32.*;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.W32APIOptions;

public class TaskManagerAppName {

    public interface Shell32 extends com.sun.jna.platform.win32.Shell32 {
        Shell32 INSTANCE = Native.load("shell32", Shell32.class, W32APIOptions.DEFAULT_OPTIONS);
        int SHGetFileInfoW(WinDef.LPCWSTR pszPath, int dwFileAttributes, SHFILEINFOW psfi, int cbFileInfo, int uFlags);
    }

    public static void main(String[] args) {
        User32 user32 = User32.INSTANCE;
        WinDef.HWND hwnd = user32.GetForegroundWindow();
        IntByReference processId = new IntByReference();
        user32.GetWindowThreadProcessId(hwnd, processId);
        int pid = processId.getValue();

        // 打开进程获取可执行文件路径
        WinNT.HANDLE processHandle = Kernel32.INSTANCE.OpenProcess(
                WinNT.PROCESS_QUERY_INFORMATION | WinNT.PROCESS_VM_READ, false, pid);
        char[] exePath = new char[1024];
        Psapi.INSTANCE.GetModuleFileNameExW(processHandle, null, exePath, exePath.length);
        String exePathStr = Native.toString(exePath);
        Kernel32.INSTANCE.CloseHandle(processHandle);

        // 获取Win32应用的显示名称(任务管理器显示的名称)
        Shell32.SHFILEINFOW shfi = new Shell32.SHFILEINFOW();
        int result = Shell32.INSTANCE.SHGetFileInfoW(new WinDef.LPCWSTR(exePathStr), 0, shfi, shfi.size(),
                Shell32.SHGFI_DISPLAYNAME | Shell32.SHGFI_USEFILEATTRIBUTES);

        String appName;
        if (result != 0) {
            appName = Native.toString(shfi.szDisplayName);
        } else {
            // 处理UWP应用,通过PowerShell获取包显示名称
            appName = getUwpAppName(pid);
            if (appName == null) {
                // 降级到exe名称作为备选
                appName = exePathStr.substring(exePathStr.lastIndexOf("\\") + 1).replace(".exe", "");
            }
        }

        System.out.println("任务管理器显示名称: " + appName);
    }

    // 获取UWP应用的显示名称
    private static String getUwpAppName(int pid) {
        try {
            // 调用PowerShell命令查询UWP应用包信息
            Process process = Runtime.getRuntime().exec(
                    "powershell -Command \"Get-Process -Id " + pid + " | Select-Object -ExpandProperty Path | Get-AppxPackage -PackageTypeFilter Main | Select-Object -ExpandProperty DisplayName\"");
            process.waitFor();
            String output = new String(process.getInputStream().readAllBytes()).trim();
            return output.isEmpty() ? null : output;
        } catch (Exception e) {
            return null;
        }
    }
}

代码说明

  • SHGetFileInfoW:系统API,直接读取可执行文件的显示名称,完美匹配任务管理器中Win32应用的名称(如idea64.exe对应IntelliJ IDEA)
  • UWP应用处理:通过PowerShell调用系统命令,获取UWP应用的包显示名称,解决“设置”这类应用显示为Applicationframehost的问题
  • 降级逻辑:当以上方法失效时,自动回退到exe名称,保证基础可用性

内容的提问来源于stack exchange,提问作者Mat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 00:57:20