stricmp 在我的代码中不起作用
stricmp doesn't work in my code
我正在循环浏览 TlHelp32 的进程快照,然后将名称与 stricmp 进行比较以获取进程句柄。问题是即使两个值看起来相同,但它们显然不是,因为它不是 return 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;
}
我调试它以查看这些值是否合适:
在处理 wchar*
数据类型时,使用 _wcsicmp
进行比较,并且 - 如有必要 - 将任何涉及的 char*
数据类型转换为 wchar*
等价的数据类型,例如使用 CStringW class。授予 microsoft _wcsicmp, and be also aware of using a correct locale. A similar problem, yet with wchar* constants, has been described at stack overflow
问题是您正在使用 TCHAR
版本的 Process32First()
/Process32Next()
,并且您的调试器屏幕截图清楚地显示您正在为 Unicode 编译项目,所以 TCHAR
映射到 WCHAR
,因此 process.szExeFile
是一个 WCHAR[]
数组。您将该数组错误地类型转换为 char*
指针。您不能直接将 Unicode 字符串与 Ansi 字符串进行比较。在比较它们之前,您需要将一个字符串转换为另一个字符串的编码。
您还泄露了 CreateToolhelp32Snapshot()
返回的 HANDLE
。
由于您将 Ansi std::string
作为输入传递给 GetProcessValues()
函数,最简单的 解决方案是使用 Ansi 版本的 Process32First()
/Process32Next()
相反,因此 process.szExeFile
现在是一个 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;
}
但是,您真的应该远离使用 Ansi APIs。 Windows 是基于 Unicode 的 OS,并且已经存在了很长时间。使用 Unicode APIs 代替:
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;
}
如果您的 ProcName
参数绝对必须是 std::string
,那么您可以:
使用 MultiByteToWideChar()
、std::wstring_convert
等将 ProcName
转换为 Unicode,然后将该结果与 Unicode API 返回的字符串进行比较.
使用 WideCharToMultiByte()
、std::wstring_convert
等将字符串从 Unicode API 转换为 Ansi,然后将这些结果与 ProcName
进行比较。 =36=]
我正在循环浏览 TlHelp32 的进程快照,然后将名称与 stricmp 进行比较以获取进程句柄。问题是即使两个值看起来相同,但它们显然不是,因为它不是 return 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;
}
我调试它以查看这些值是否合适:
在处理 wchar*
数据类型时,使用 _wcsicmp
进行比较,并且 - 如有必要 - 将任何涉及的 char*
数据类型转换为 wchar*
等价的数据类型,例如使用 CStringW class。授予 microsoft _wcsicmp, and be also aware of using a correct locale. A similar problem, yet with wchar* constants, has been described at stack overflow
问题是您正在使用 TCHAR
版本的 Process32First()
/Process32Next()
,并且您的调试器屏幕截图清楚地显示您正在为 Unicode 编译项目,所以 TCHAR
映射到 WCHAR
,因此 process.szExeFile
是一个 WCHAR[]
数组。您将该数组错误地类型转换为 char*
指针。您不能直接将 Unicode 字符串与 Ansi 字符串进行比较。在比较它们之前,您需要将一个字符串转换为另一个字符串的编码。
您还泄露了 CreateToolhelp32Snapshot()
返回的 HANDLE
。
由于您将 Ansi std::string
作为输入传递给 GetProcessValues()
函数,最简单的 解决方案是使用 Ansi 版本的 Process32First()
/Process32Next()
相反,因此 process.szExeFile
现在是一个 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;
}
但是,您真的应该远离使用 Ansi APIs。 Windows 是基于 Unicode 的 OS,并且已经存在了很长时间。使用 Unicode APIs 代替:
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;
}
如果您的 ProcName
参数绝对必须是 std::string
,那么您可以:
使用
MultiByteToWideChar()
、std::wstring_convert
等将ProcName
转换为 Unicode,然后将该结果与 Unicode API 返回的字符串进行比较.使用
WideCharToMultiByte()
、std::wstring_convert
等将字符串从 Unicode API 转换为 Ansi,然后将这些结果与ProcName
进行比较。 =36=]