如何在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启动一个进程后,第二次启动先读取进程列表判断目标进程是否存在,存在就跳过。
浙公网安备 33010602011771号