stricmp在我的代码中不起作用

时间:2016-12-13 21:59:16

标签: c++ winapi comparison data-conversion

我正在循环查看TlHelp32的进程快照,然后将名称与stricmp进行比较以获取进程句柄。问题是即使两个值看起来都相同,但它们显然不是因为它不会返回0。我不知道为什么,我也尝试将进程名称写入函数中。

HANDLE GetProcessValues(std::string ProcName)
{
   const char* ProcNameChar = ProcName.c_str();
   HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
   PROCESSENTRY32 process;
   ZeroMemory(&process, sizeof(process));
   process.dwSize = sizeof(process);
   if (Process32First(snapshot, &process))
   {
       do
       {
           if (_stricmp((char*)process.szExeFile,ProcNameChar)==0)
           {
               HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);
               return hProc;
           }
       }while (Process32Next(snapshot,&process));
   }
   return 0;
}

我调试它以查看值是否合适: Screenshot

2 个答案:

答案 0 :(得分:2)

问题是您使用TCHAR / Process32First()的{​​{1}}版本,并且您的调试器screnshot清楚地显示您正在为Unicode编译项目,因此{{1} }映射到Process32Next(),因此TCHARWCHAR数组。您错误地将该数组类型转换为process.szExeFile指针。您无法直接将Unicode字符串与Ansi字符串进行比较。您需要将一个字符串转换为另一个字符串的编码,然后再进行比较。

您还在泄露WCHAR[]返回的char*

由于您将Ansi HANDLE作为输入传递给CreateToolhelp32Snapshot()函数,因此最简单的解决方案将使用 Ansi 版本std::string / GetProcessValues()代替,Process32First()现在是Process32Next()数组,因此无需转换:

process.szExeFile

但是,您真的应该远离使用 Ansi API。 Windows是基于Unicode的操作系统,并且已经存在了很长时间。请改用 Unicode API:

CHAR[]

如果您的HANDLE GetProcessValues(std::string ProcName) { HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot == INVALID_HANDLE_VALUE) return NULL; PROCESSENTRY32A process; ZeroMemory(&process, sizeof(process)); process.dwSize = sizeof(process); const char* ProcNameChar = ProcName.c_str(); HANDLE hProc = NULL; if (Process32FirstA(snapshot, &process)) { do { if (_stricmp(process.szExeFile, ProcNameChar) == 0) { hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID); break; } } while (Process32NextA(snapshot, &process)); } CloseHandle(snapshot); return hProc; } 参数绝对必须是HANDLE GetProcessValues(std::wstring ProcName) { HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot == INVALID_HANDLE_VALUE) return NULL; PROCESSENTRY32W process; ZeroMemory(&process, sizeof(process)); process.dwSize = sizeof(process); const wchar_t* ProcNameChar = ProcName.c_str(); HANDLE hProc = NULL; if (Process32FirstW(snapshot, &process)) { do { if (_wcsicmp(process.szExeFile, ProcNameChar) == 0) { hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID); break; } } while (Process32NextW(snapshot, &process)); } CloseHandle(snapshot); return hProc; } ,那么您可以:

  1. 使用ProcNamestd::string等将ProcName转换为Unicode,然后将该结果与Unicode API返回的字符串进行比较。

  2. 使用MultiByteToWideChar()std::wstring_convert等将Unicode API中的字符串转换为Ansi,然后将这些结果与WideCharToMultiByte()进行比较。

答案 1 :(得分:1)

在处理wchar*数据类型时,使用_wcsicmp进行比较,并且 - 如有必要 - 将所有涉及的char*数据类型转换为wchar* - 等效数据,例如使用CStringW类。授予microsoft _wcsicmp,并且还要注意使用正确的区域设置。使用wchar *常量的类似问题已在stack overflow

中描述