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

Windows系统中如何获取应用名称及关联进程?求代码示例

在Windows中获取应用名称及对应进程的实现方案

Windows任务管理器中的“应用名称”通常对应进程的窗口标题、应用程序产品名称(从可执行文件版本信息读取),或是UWP应用的包名称。以下是PowerShell、Python、Java的实现示例,实现类似任务管理器的应用-进程关联展示:


一、PowerShell实现

结合Get-Process与WMI/CIM获取进程详细信息,同时对同一应用的进程进行分组:

1. 桌面应用(含窗口)+ 进程分组

# 获取所有进程,补充产品名称和窗口标题
$processes = Get-Process | ForEach-Object {
    $exePath = $_.Path
    $productName = $null
    if ($exePath) {
        # 从可执行文件版本信息获取产品名称
        $versionInfo = (Get-Item $exePath).VersionInfo
        $productName = $versionInfo.ProductName
    }
    [PSCustomObject]@{
        PID = $_.Id
        ProcessName = $_.Name
        AppName = if ($productName) { $productName } else { if ($_.MainWindowTitle -eq "") { "后台进程" } else { $_.MainWindowTitle } }
        ExePath = $exePath
    }
}

# 按应用名称分组展示
$processes | Group-Object -Property AppName | ForEach-Object {
    Write-Host "=== 应用名称: $($_.Name) ==="
    $_.Group | Select-Object PID, ProcessName, ExePath | Format-Table -AutoSize
}

2. 包含UWP应用的扩展版本

# 获取UWP应用的包信息与进程关联
$uwpProcesses = Get-CimInstance Win32_Process | Where-Object { $_.ExecutablePath -like "*\WindowsApps\*" } | ForEach-Object {
    $packageFolder = Split-Path $_.ExecutablePath -Parent
    $packageName = ($packageFolder -split "\\")[ -2 ]
    $appName = (Get-AppxPackage -Name $packageName).DisplayName
    [PSCustomObject]@{
        PID = $_.ProcessId
        ProcessName = $_.Name
        AppName = if ($appName) { $appName } else { $packageName }
        ExePath = $_.ExecutablePath
    }
}

# 合并桌面应用与UWP应用并分组展示
($processes + $uwpProcesses) | Group-Object -Property AppName | ForEach-Object {
    Write-Host "=== 应用名称: $($_.Name) ==="
    $_.Group | Select-Object PID, ProcessName, ExePath | Format-Table -AutoSize
}

二、Python实现

使用psutil获取进程基础信息,结合pywin32读取可执行文件的版本信息来获取应用名称,实现进程分组:

1. 依赖安装

pip install psutil pywin32

2. 代码实现

import psutil
import win32api
from collections import defaultdict

def get_app_name(exe_path):
    """从可执行文件路径获取应用产品名称"""
    try:
        # 获取文件版本信息
        file_version_info = win32api.GetFileVersionInfo(exe_path, "\\")
        # 提取产品名称
        lang, codepage = win32api.GetFileVersionInfo(exe_path, "\\VarFileInfo\\Translation")[0]
        str_info_path = f"\\StringFileInfo\\{lang:04x}{codepage:04x}\\ProductName"
        return file_version_info[str_info_path]
    except Exception:
        return None

# 按应用名称分组存储进程
app_process_map = defaultdict(list)

for proc in psutil.process_iter(['pid', 'name', 'exe', 'main_window_title']):
    try:
        proc_info = proc.info
        exe_path = proc_info['exe']
        app_name = get_app_name(exe_path)
        
        # 优先级:产品名称 > 主窗口标题 > 进程名称
        if not app_name:
            app_name = proc_info['main_window_title'] if proc_info['main_window_title'] else proc_info['name']
        
        # 添加到对应应用分组
        app_process_map[app_name].append({
            'pid': proc_info['pid'],
            'process_name': proc_info['name'],
            'window_title': proc_info['main_window_title']
        })
    except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
        continue

# 打印结果
for app_name, processes in app_process_map.items():
    print(f"=== 应用名称: {app_name} ===")
    for proc in processes:
        print(f"PID: {proc['pid']}, 进程名: {proc['process_name']}, 窗口标题: {proc['window_title']}")
    print("-" * 50)

三、Java实现

通过JNA调用Windows原生API获取进程的可执行文件路径,再读取文件版本信息中的产品名称,实现应用-进程关联:

1. 依赖(Maven)

<dependencies>
    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna</artifactId>
        <version>5.13.0</version>
    </dependency>
    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna-platform</artifactId>
        <version>5.13.0</version>
    </dependency>
</dependencies>

2. 代码实现

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.*;
import com.sun.jna.ptr.IntByReference;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;

public class WindowsAppProcessLister {

    // 获取进程的可执行文件路径
    private static String getProcessExePath(int pid) {
        WinNT.HANDLE processHandle = Kernel32.INSTANCE.OpenProcess(
                WinNT.PROCESS_QUERY_INFORMATION | WinNT.PROCESS_VM_READ,
                false, pid);
        if (processHandle == null || processHandle.equals(WinNT.HANDLE.INVALID_HANDLE_VALUE)) {
            return null;
        }

        char[] exePath = new char[WinDef.MAX_PATH];
        Psapi.INSTANCE.GetModuleFileNameExW(processHandle, null, exePath, exePath.length);
        Kernel32.INSTANCE.CloseHandle(processHandle);
        return Native.toString(exePath).trim();
    }

    // 从文件路径获取应用产品名称
    private static String getAppProductName(String exePath) {
        if (exePath == null || exePath.isEmpty()) return null;
        File file = new File(exePath);
        if (!file.exists()) return null;

        try {
            VersionInfo versionInfo = VersionInfo.getVersionInfo(file.getAbsolutePath());
            return versionInfo.getProductName();
        } catch (Exception e) {
            return null;
        }
    }

    public static void main(String[] args) {
        Map<String, List<ProcessInfo>> appProcessMap = new HashMap<>();

        // 枚举所有进程ID
        IntByReference processCount = new IntByReference();
        int[] processIds = new int[1024];
        if (!Psapi.INSTANCE.EnumProcesses(processIds, processIds.length * 4, processCount)) {
            System.err.println("枚举进程失败");
            return;
        }

        int count = processCount.getValue() / 4;
        for (int i = 0; i < count; i++) {
            int pid = processIds[i];
            if (pid == 0) continue;

            String exePath = getProcessExePath(pid);
            String appName = getAppProductName(exePath);
            if (appName == null) {
                appName = exePath != null ? new File(exePath).getName() : "未知进程";
            }

            ProcessInfo info = new ProcessInfo(pid, exePath);
            appProcessMap.computeIfAbsent(appName, k -> new ArrayList<>()).add(info);
        }

        // 打印结果
        for (Map.Entry<String, List<ProcessInfo>> entry : appProcessMap.entrySet()) {
            System.out.println("=== 应用名称: " + entry.getKey() + " ===");
            for (ProcessInfo info : entry.getValue()) {
                System.out.printf("PID: %d, 可执行路径: %s%n", info.pid, info.exePath);
            }
            System.out.println("--------------------------------------------------");
        }
    }

    static class ProcessInfo {
        int pid;
        String exePath;

        public ProcessInfo(int pid, String exePath) {
            this.pid = pid;
            this.exePath = exePath;
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 11:05:46