2016-12-13 7 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 * not char *. – drescherjm

+6

Почему вы применили 'char *' в первом аргументе '_stricmp'? Если бы было закрыто компилятор о ошибке несоответствия типа, прекратите делать это и предоставите правильный тип строки функции. Никогда не применяйте строковые типы - отливка ** не ** конверсия. – PaulMcKenzie

+5

Вы лгали компилятору и получили ваши десерты –

ответ

2

Проблема в том, что вы используете TCHAR версии Process32First()/Process32Next(), и ваш отладчик screnshot ясно показывает, что вы компиляции проекта для Unicode, так TCHAR соответствует WCHAR и таким образом process.szExeFile является массивом WCHAR[]. Вы неправильно набираете этот массив для указателя char*. Вы не можете напрямую сравнивать строку Unicode с строкой Ansi. Вам нужно преобразовать одну строку в кодировку другой строки, а затем сравнить ее.

Вы также просачиваете HANDLE, возвращенный CreateToolhelp32Snapshot().

Поскольку вы пропускание 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; 
} 

Однако, вы действительно должны держаться подальше от использования Анси API. Windows - это ОС на базе Unicode и долгое время. Используйте 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. конвертировать ProcName в Unicode с использованием MultiByteToWideChar(), std::wstring_convert и т.д., а затем сравнить это результат для строк, возвращаемых API Unicode.

  2. преобразования строк из API Unicode в ANSI с помощью WideCharToMultiByte(), std::wstring_convert и т.д., а затем сравнить эти результаты ProcName.

1

при работе с wchar* типом данных, используйте _wcsicmp для сравнения, а также - при необходимости - конвертировать любой участвующих char* типа данных в wchar* - эквивалент, например используя класс CStringW. Confer microsoft _wcsicmp, а также знать, как использовать правильный язык. Аналогичная проблема, но с WChar * констант, была описана в stack overflow

+0

'wchar *' не является интегральным типом данных в C++. Вы смешиваете это с C++ 'wchar_t * 'или Windows WKK WCHAR *. Кроме того, 'CStringW' является (предположительно) шаблоном класса MFC/ATL. Если вы не пишете код MFC или ATL, это неприменимо (как правило, это не для программирования Windows API). Функция преобразования в API Windows - [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

 Смежные вопросы

  • Нет связанных вопросов^_^