2016-12-13 2 views
-2

Ich fahre durch einen Prozess Snapshot von TlHelp32 und dann vergleicht die Namen mit stricmp, um den Prozess zu erhalten. Das Problem ist, obwohl beide Werte gleich zu sein scheinen, sie sind anscheinend nicht, da es 0 nicht zurückgibt. Ich weiß nicht warum, aber ich habe versucht, den Prozessnamen in die Funktion zu schreiben.stricmp funktioniert nicht in meinem Code

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; 
} 

ich gedebuggt es, wenn die Werte passen, um zu sehen: Screenshot

+1

Von Ihrem Image 'process.szExeFile' ist ein wchar * nicht char *. – drescherjm

+6

Warum haben Sie im ersten Argument von _stricmp auf "char *" gecastet? Wenn der Compiler über einen Typenkonfliktfehler geschlossen werden sollte, beenden Sie das und geben Sie der Funktion den korrekten Zeichenfolientyp an. Niemals String-Typen - Casting ist ** nicht ** Konvertierung. – PaulMcKenzie

+5

Sie haben den Compiler angelogen und haben Ihre Desserts bekommen –

Antwort

2

Das Problem beschrieben worden ist, dass Sie die TCHAR Versionen von Process32First()/Process32Next() verwenden und Ihre Debugger screnshot zeigen deutlich, dass Sie Ihr Projekt für Unicode kompilieren, so TCHAR Karten zu WCHAR und somit process.szExeFile ist ein WCHAR[] Array. Sie geben dieses Array fälschlicherweise an einen Zeiger char*. Sie können eine Unicode-Zeichenfolge nicht direkt mit einer Ansi-Zeichenfolge vergleichen. Sie müssen eine Zeichenfolge in die Codierung der anderen Zeichenfolge konvertieren, bevor Sie sie vergleichen.

Sie lecken auch die HANDLE zurückgegeben von CreateToolhelp32Snapshot().

Da Sie eine Ansi std::string als Eingabe für Ihre GetProcessValues() Funktion sind vorbei, die einfachste Lösung wäre, die Ansi Versionen von Process32First()/Process32Next() stattdessen zu verwenden, so process.szExeFile ist nun ein CHAR[] Array und somit keine Konvertierung gebraucht wird:

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; 
} 

Allerdings sollten Sie wirklich bleiben weg Ansi APIs verwenden. Windows ist ein Unicode-basiertes Betriebssystem und das schon lange. Verwenden Sie Unicode APIs statt:

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; 
} 

Wenn Ihr ProcName Parameter unbedingt ein std::string sein muss, dann können Sie entweder:

  1. konvertieren ProcName in Unicode mit MultiByteToWideChar(), std::wstring_convert, etc, und dann vergleichen Dieses Ergebnis entspricht den Strings, die von der Unicode-API zurückgegeben werden.

  2. konvertieren Zeichenfolgen aus der Unicode-API Ansi WideCharToMultiByte() verwenden, std::wstring_convert, etc, und dann diese Ergebnisse zu ProcName vergleichen.

1

, wenn sie mit wchar* Datentyp handelt, zum Vergleich _wcsicmp verwenden, und - falls erforderlich - wandelt jeden beteiligten char* Datentyp in ein wchar* - gleichwertig, z Verwenden der CStringW-Klasse. Übergeben Sie microsoft _wcsicmp, und achten Sie auch auf die Verwendung eines korrekten Gebietsschemas. Ein ähnliches Problem, aber mit wchar * Konstanten hat bei stack overflow

+0

'wchar *' ist kein integraler Datentyp in C++. Sie verwechseln das mit C++ 's wchar_t * 'oder dem Windows SDK' WCHAR * '. Außerdem ist 'CStringW' (vermutlich) eine MFC/ATL-Klassenvorlage. Sofern Sie MFC- oder ATL-Code nicht schreiben, ist dies nicht anwendbar (es ist im Allgemeinen nicht für Windows-API-Programmierung). Die Konvertierungsfunktion in der Windows-API lautet [MultiByteToWideChar] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd319072.aspx). Eine C++ - Alternative wäre [std :: mbstowcs] (http://en.cppreference.com/w/cpp/string/multibyte/mbstowcs). – IInspectable

Verwandte Themen