2016-12-13 9 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

なぜ '_stricmp'の最初の引数で' char * 'にキャストしましたか?コンパイラが型の不一致エラーについてシャットダウンする場合は、それをやめ、正しい文字列型を関数に渡します。文字列型をキャストしない - キャストは**変換ではありません**。 – PaulMcKenzie

+5

あなたはコンパイラに嘘をついて、ちょうどデザートを手に入れました –

答えて

2

に記載されている問題は、あなたがProcess32First()/Process32Next()TCHARのバージョンを使用していることで、あなたのデバッガscrenshotは明らかにそう、あなたがUnicodeのプロジェクトをコンパイルしていることを示していますTCHARWCHARにマップし、従ってprocess.szExeFileWCHAR[]アレイです。その配列をchar*ポインターに誤って型変換しています。 Unicode文字列とAnsi文字列を直接比較することはできません。ある文字列を他の文字列のエンコーディングに変換してから比較する必要があります。

さらにHANDLEがリークしています(CreateToolhelp32Snapshot())。

あなたGetProcessValues()関数への入力などのANSI std::stringを渡しているので、最も簡単な解決策ではなく、Process32First()/Process32Next()のAnsiバージョンを使用することですので、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 APIを使用してから離れて滞在する必要があります。 WindowsはUnicodeベースのOSであり、長い間続いてきました。代わりにユニコード 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を使用してUnicodeにProcNameを変換し、比較その結果、Unicode APIによって返される文字列になります。

  2. WideCharToMultiByte(),std::wstring_convertなどを使用してUnicode APIからAnsiに文字列を変換し、その結果をProcNameと比較してください。

1

wchar*データ型を扱うとき、比較のために_wcsicmpを使用し、 - 必要ならば - wchar*に何らかの関与char*のデータ型を変換します - 等価、例えばCStringWクラスを使用します。 Confer 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

関連する問題