如何在Qt/Windows上实现“拿到电脑上运行的所有进程”的名称,以及关于QProcess的总结

最近在做一个需求,需要检测我即将打开的软件是否正在运行,如果在运行就不再二次启动,我选择的简单方案是通过windows自带的tasklist.exe获取进程名称。问题的关键在于如何拿到电脑上所有的进程列表。
代码如下:

#include <windows.h>
#include <psapi.h>

#pragma comment(lib, "psapi.lib")

struct ProcessInfo
{
    int pid;
    QString name;      // 进程名(如 "chrome.exe")
};

QVector<GlobalTool::ProcessInfo> GlobalTool::getAllRunningProcesses()
{
    QVector<ProcessInfo> processes;

    // Windows: 使用 tasklist /FO CSV
    QProcess process;
    process.start("tasklist", QStringList() << "/FO" << "CSV");
    process.waitForFinished();
    QByteArray output = process.readAllStandardOutput();

    // 解析 CSV 格式
    QString outputStr = QString::fromUtf8(output);
    QStringList lines = outputStr.split('\n');
    for (int i = 1; i < lines.size(); ++i) { // 跳过标题行
        QString line = lines[i].trimmed();
        if (line.isEmpty()) continue;

        // CSV: "Image Name","PID","Session Name","Session#","Mem Usage"
        QStringList fields = line.split(',');
        if (fields.size() < 2) continue;

        // 提取进程名(去掉引号)
        QString name = fields[0].remove('"');
        // 提取 PID
        bool ok;
        int pid = fields[1].remove('"').toInt(&ok);
        if (ok) {
            ProcessInfo info;
            info.pid = pid;
            info.name = name;
            processes.append(info);
        }
    }

    return processes;
}

关于QProcess
另外一个事情是,QProcess启动另外一个进程,有两种方式,有控制和无控制。

1、同步启动
可以通信,可以监听是否挂掉或成功启动,可以用QProcess的read和write与软件的std::cin和std::cout进行双向通信。
重点:可以通过监听finished判断是否退出了。
QProcess p;
p.start();

2、异步启动
startDetached()失去控制权,异步,无法通信,没有父子关系,互相独立存在。

总结:一个是读取Windows进程列表,另一个是QProcess的启动,这两个可能在解决一个问题的时候同时遇到。就比如用startDetached启动一个进程后,第二次启动先读取进程列表判断目标进程是否存在,存在就跳过。

posted @ 2025-11-14 09:04  LiZhaoyue888  阅读(16)  评论(0)    收藏  举报