2016-12-13 18 views
-2

我通過TlHelp32的進程快照循環,然後將名稱與stricmp進行比較以獲取進程句柄。問題是即使兩個值看起來都是相同的,但它們顯然不是因爲它不返回0。我不知道爲什麼,但我已經嘗試將進程名寫入函數中。stricmp不能在我的代碼中工作

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

+1

從你的圖片'process.szExeFile'是一個wchar *不是char *。 – drescherjm

+6

爲什麼你在'_stricmp'的第一個參數中轉換爲'char *'?如果是關閉類型不匹配錯誤的編譯器,停止這樣做併爲函數提供正確的字符串類型。永遠不會投射字符串類型 - 投射是**不是**轉換。 – PaulMcKenzie

+5

你對編譯器撒謊了,並且得到了你剛纔的甜點 –

回答

2

的問題進行了描述是,你正在使用的TCHAR版本Process32First()/Process32Next(),和你的調試器screnshot清楚地表明,你正在編譯您對Unicode的項目,所以TCHAR映射到WCHAR,因此process.szExeFileWCHAR[]陣列。您錯誤地將該數組類型轉換爲char*指針。您不能直接將Unicode字符串與Ansi字符串進行比較。在比較之前,您需要將一個字符串轉換爲另一個字符串的編碼。

您還在泄漏CreateToolhelp32Snapshot()返回的HANDLE

因爲你是傳遞一個ANSI std::string輸入您GetProcessValues()功能,最簡單的解決辦法是使用安思版本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; 
} 

但是,你真的應該使用安西的API望而卻步。 Windows是一個基於Unicode的操作系統,並且已經有很長一段時間了。使用統一的API,而不是:

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,那麼您可以:

  1. 使用MultiByteToWideChar()std::wstring_convert等轉換ProcName爲Unicode,然後比較這會導致Unicode API返回的字符串。

  2. 使用WideCharToMultiByte()std::wstring_convert等將字符串從Unicode API轉換爲Ansi,然後將這些結果與ProcName進行比較。

1

wchar*數據類型打交道時,使用_wcsicmp進行比較,和 - 如果需要的話 - 將任何涉及char*數據類型爲wchar* - 相當於,例如使用CStringW類。授予microsoft _wcsicmp,並且也知道使用正確的語言環境。類似的問題,但與WCHAR *常量,曾在stack overflow

+0

'wchar *'不是C++中的整數數據類型。你用C++的'wchar_t *'或Windows SDK的'WCHAR *'搞混了。除此之外,'CStringW'(可能是)MFC/ATL類模板。除非你正在編寫MFC或ATL代碼,否則這是不適用的(它通常不適用於Windows API編程)。 Windows API中的轉換函數是[MultiByteToWideChar](https://msdn.microsoft.com/en-us/library/windows/desktop/dd319072.aspx)。一個C++的替代方案是[std :: mbstowcs](http://en.cppreference.com/w/cpp/string/multibyte/mbstowcs)。 – IInspectable