Windows下C++通过进程名获取PID遇类型不兼容错误求助
解决进程名获取PID时的字符类型不兼容问题
错误原因解析
procEntry.szExeFile 是 WCHAR 类型的宽字符数组*,而你用来比较的字符串是 const char* 多字节类型,两者字符编码不匹配导致类型错误(错误代码167)。重装C++库无法解决这个问题,核心是字符集不统一或类型转换方式不正确。
直接修复当前错误的方法
方法1:统一使用Unicode字符集(推荐)
Windows API默认优先支持宽字符版本,修改项目字符集设置为Unicode,然后用宽字符字面量匹配:
- 打开项目属性 → 配置属性 → 常规 → 字符集,选择「使用Unicode字符集」
- 修改字符串比较代码,给进程名加上
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
相关产品推荐
相关产品推荐

