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

如何在Windows下用C++检测进程是否已运行并控制CreateProcess创建逻辑?

Windows下检测进程运行状态与避免重复创建进程的实现方案

一、C++检测进程是否运行的方法

1. 通过进程快照(Toolhelp32)检测进程名

这是最常用的通用方法,遍历系统中所有进程并匹配进程名:

#include <windows.h>
#include <tlhelp32.h>
#include <string>
#include <cwchar>

bool IsProcessRunning(const std::wstring& processName) {
    // 创建进程快照
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        return false;
    }

    PROCESSENTRY32 pe32{};
    pe32.dwSize = sizeof(PROCESSENTRY32);

    // 获取第一个进程信息
    if (!Process32First(hSnapshot, &pe32)) {
        CloseHandle(hSnapshot);
        return false;
    }

    // 遍历所有进程
    do {
        // 不区分大小写匹配进程名
        if (_wcsicmp(pe32.szExeFile, processName.c_str()) == 0) {
            CloseHandle(hSnapshot);
            return true;
        }
    } while (Process32Next(hSnapshot, &pe32));

    CloseHandle(hSnapshot);
    return false;
}

注意事项:

  • 32位程序在64位系统中只能检测到32位进程,若要检测64位进程,需编译为64位程序或使用底层系统API(如NtQuerySystemInformation)
  • 进程名可能存在重名(如多个notepad.exe),若需精确匹配特定实例,需结合进程ID、窗口标题或互斥体等信息

2. 通过命名互斥体实现唯一实例(最可靠)

如果是确保自身程序只运行一个实例,或者目标程序支持互斥体检测,使用命名互斥体是最优方案,能避免竞态条件:

#include <windows.h>
#include <iostream>

int main() {
    // 全局命名互斥体,前缀Global\可跨用户会话检测(如服务与桌面进程)
    HANDLE hMutex = CreateMutexW(NULL, TRUE, L"Global\\MyUniqueApp_{F4D1A920-785E-4C2A-8F9D-5C3B8E1B1E11}");
    if (hMutex == NULL) {
        std::cerr << "创建互斥体失败,错误码:" << GetLastError() << std::endl;
        return 1;
    }

    // 检查是否已有实例运行
    if (GetLastError() == ERROR_ALREADY_EXISTS) {
        MessageBoxW(NULL, L"程序已在运行中", L"提示", MB_OK | MB_ICONINFORMATION);
        CloseHandle(hMutex);
        return 0;
    }

    // 执行程序核心逻辑,包括调用CreateProcess启动外部进程
    // ...

    // 程序退出前释放互斥体
    CloseHandle(hMutex);
    return 0;
}

注意事项:

  • 互斥体名称需全局唯一,建议使用GUID避免冲突
  • 若仅需当前用户会话内唯一,可去掉Global\\前缀

3. 通过窗口标题检测

如果目标进程有唯一可识别的窗口标题,可直接查找窗口:

#include <windows.h>
#include <string>

bool IsTargetWindowRunning(const std::wstring& windowTitle) {
    HWND hWnd = FindWindowW(NULL, windowTitle.c_str());
    return hWnd != NULL;
}

局限性:窗口标题可能动态变化,或多个窗口使用相同标题,可靠性较低


二、结合CreateProcess实现「已运行则不创建」逻辑

先检测目标进程状态,再决定是否调用CreateProcess:

#include <windows.h>
#include <tlhelp32.h>
#include <string>
#include <iostream>

bool IsProcessRunning(const std::wstring& processName) {
    // 实现同上述快照方法
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) return false;

    PROCESSENTRY32 pe32{};
    pe32.dwSize = sizeof(PROCESSENTRY32);
    if (!Process32First(hSnapshot, &pe32)) {
        CloseHandle(hSnapshot);
        return false;
    }

    do {
        if (_wcsicmp(pe32.szExeFile, processName.c_str()) == 0) {
            CloseHandle(hSnapshot);
            return true;
        }
    } while (Process32Next(hSnapshot, &pe32));

    CloseHandle(hSnapshot);
    return false;
}

int main() {
    const std::wstring targetExe = L"notepad.exe";

    if (!IsProcessRunning(targetExe)) {
        STARTUPINFOW si{};
        PROCESS_INFORMATION pi{};
        si.cb = sizeof(si);

        // 注意:第二个参数需为可修改的字符串,若传入const需强制转换(确保内存可写)
        wchar_t cmdLine[MAX_PATH] = {0};
        wcscpy_s(cmdLine, targetExe.c_str());

        if (CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
            std::wcout << L"进程创建成功,PID:" << pi.dwProcessId << std::endl;
            // 关闭进程与线程句柄(无需等待时立即关闭)
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
        } else {
            std::wcerr << L"创建进程失败,错误码:" << GetLastError() << std::endl;
        }
    } else {
        std::wcout << L"目标进程" << targetExe << L"已在运行" << std::endl;
    }

    return 0;
}

三、外部检测方法(无需编写代码)

1. 命令行工具

  • tasklist:

    tasklist /fi "imagename eq notepad.exe"
    

    若输出包含notepad.exe,则进程正在运行

  • wmic:

    wmic process where name="notepad.exe" get processid
    

    有返回结果则进程运行中

2. PowerShell命令

Get-Process -Name notepad -ErrorAction SilentlyContinue

若返回非空结果,说明进程正在运行


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 18:55:34