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

Windows下C++通过进程名获取PID遇类型不兼容错误求助

解决进程名获取PID时的字符类型不兼容问题

错误原因解析

procEntry.szExeFile 是 WCHAR 类型的宽字符数组*,而你用来比较的字符串是 const char* 多字节类型,两者字符编码不匹配导致类型错误(错误代码167)。重装C++库无法解决这个问题,核心是字符集不统一或类型转换方式不正确。

直接修复当前错误的方法

方法1:统一使用Unicode字符集(推荐)

Windows API默认优先支持宽字符版本,修改项目字符集设置为Unicode,然后用宽字符字面量匹配:

  1. 打开项目属性 → 配置属性 → 常规 → 字符集,选择「使用Unicode字符集」
  2. 修改字符串比较代码,给进程名加上L前缀(表示宽字符):
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>

DWORD GetProcessIdByName(const wchar_t* processName) {
    PROCESSENTRY32 procEntry;
    procEntry.dwSize = sizeof(PROCESSENTRY32);

    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        return 0;
    }

    if (Process32First(hSnapshot, &procEntry)) {
        do {
            // 直接比较宽字符字符串
            if (_wcsicmp(procEntry.szExeFile, processName) == 0) {
                CloseHandle(hSnapshot);
                return procEntry.th32ProcessID;
            }
        } while (Process32Next(hSnapshot, &procEntry));
    }

    CloseHandle(hSnapshot);
    return 0;
}

// 调用示例
int main() {
    DWORD pid = GetProcessIdByName(L"notepad.exe");
    if (pid != 0) {
        std::wcout << L"进程ID: " << pid << std::endl;
    } else {
        std::wcout << L"未找到进程" << std::endl;
    }
    return 0;
}

方法2:手动转换宽字符为多字节

如果需要保留多字节字符集,使用WideCharToMultiByte将szExeFile转换为char*后再比较:

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

DWORD GetProcessIdByName(const char* processName) {
    PROCESSENTRY32 procEntry;
    procEntry.dwSize = sizeof(PROCESSENTRY32);

    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        return 0;
    }

    char exeFile[MAX_PATH];
    if (Process32First(hSnapshot, &procEntry)) {
        do {
            // 转换宽字符到多字节
            WideCharToMultiByte(CP_ACP, 0, procEntry.szExeFile, -1, exeFile, MAX_PATH, NULL, NULL);
            if (_stricmp(exeFile, processName) == 0) {
                CloseHandle(hSnapshot);
                return procEntry.th32ProcessID;
            }
        } while (Process32Next(hSnapshot, &procEntry));
    }

    CloseHandle(hSnapshot);
    return 0;
}

// 调用示例
int main() {
    DWORD pid = GetProcessIdByName("notepad.exe");
    if (pid != 0) {
        std::cout << "进程ID: " << pid << std::endl;
    } else {
        std::cout << "未找到进程" << std::endl;
    }
    return 0;
}

其他获取进程ID的方法

使用EnumProcesses + GetModuleBaseNameW

通过枚举所有进程ID,再获取每个进程的主模块名称进行匹配:

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

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

DWORD GetProcessIdByName(const wchar_t* processName) {
    DWORD processIds[1024];
    DWORD bytesReturned;

    if (!EnumProcesses(processIds, sizeof(processIds), &bytesReturned)) {
        return 0;
    }

    int numProcesses = bytesReturned / sizeof(DWORD);
    for (int i = 0; i < numProcesses; i++) {
        DWORD pid = processIds[i];
        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
        if (hProcess != NULL) {
            wchar_t moduleName[MAX_PATH];
            if (GetModuleBaseNameW(hProcess, NULL, moduleName, MAX_PATH)) {
                if (_wcsicmp(moduleName, processName) == 0) {
                    CloseHandle(hProcess);
                    return pid;
                }
            }
            CloseHandle(hProcess);
        }
    }
    return 0;
}

// 调用示例
int main() {
    DWORD pid = GetProcessIdByName(L"notepad.exe");
    if (pid != 0) {
        std::wcout << L"进程ID: " << pid << std::endl;
    } else {
        std::wcout << L"未找到进程" << std::endl;
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 04:36:17