方法一、用命令行指令
windows命令行指令tasklist可以获取当前运行的进程信息,在tasklist返回的字符串里匹配对应的进程名即可知道进程是否在运行。
例程
bool isProcessRunning(const QString &proName) {
QProcess pro;
pro.start("tasklist");
pro.waitForFinished(); //
QString output = pro.readAll();
return output.contains(proName);
}
这种方法缺点是执行得慢,有几百毫秒的延迟。
方法二、用Windows Api
windows api提供了EnumProcesses函数,可以枚举当前正常运行的进程。
官方文档:https://learn.microsoft.com/zh-cn/windows/win32/psapi/enumerating-all-processes
因为该方法是在C代码中完成,不涉及到进程间通信之类的操作,所以效率比方法一要快很多。
以下是基于官方文档改的例程:
bool checkProcessName(DWORD processID, QString processName)
{
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
if (NULL != hProcess) {
HMODULE hMod;
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
&cbNeeded) ) {
GetModuleBaseName( hProcess, hMod, szProcessName,
sizeof(szProcessName)/sizeof(TCHAR) );
}
}
CloseHandle( hProcess );
/* TChar转QString */
QString name;
for (int i = 0; i < MAX_PATH; ++i) {
int value = szProcessName[i];
if (value == 0) {
break;
}
char *ch = (char*)&value;
if (*ch != 0) {
name += *ch;
}
if (*(ch + 1) != 0) {
name += *(ch + 1);
}
}
return processName == name;
}
bool isProcessRunning(const QString &proName) {
DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) {
return false;
}
cProcesses = cbNeeded / sizeof(DWORD); //进程数量
for (i = 0; i < cProcesses; i++) {
if (aProcesses[i] != 0 &&
checkProcessName(aProcesses[i] , m_processName)) {
return true;
}
}
return false;
}