JavaEar 专注于收集分享传播有价值的技术资料

Converting and printing the module names of a process

I am trying to print and save the module names of a process.

But when printing the char array I get something that looks like an address.

#include <windows.h>
#include <TlHelp32.h>
#include <iostream>

int main() {

    MODULEENTRY32 me32;
    HWND hwnd = FindWindow(0, L"Window Name");
    DWORD dwPID;
    GetWindowThreadProcessId(hwnd, &dwPID);

    HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);

    me32.dwSize = sizeof(MODULEENTRY32);
    Module32First(hModuleSnap, &me32);
    std::cout << me32.szModule << std::endl;

    do
    {
        std::cout << me32.szModule << std::endl; // important line

    } while (Module32Next(hModuleSnap, &me32));

    return 0;
}

The output of this in my case was 00AFF53C for every module.

me32.szModule holds the name of the module as a char array.

Microsoft used the following in their example to convert and print the module name:

_tprintf( TEXT("\n\n MODULE NAME: %s"), me32.szModule );

But I think you can only use this to print the string.

So how do I convert and save the string in me32?

2个回答

    最佳答案
  1. 参考答案2
  2. Your project is being compiled with UNICODE defined (as evident by you being able to pass a wide string to FindWindow()). That causes Module32(First|Next) to map to Module32(First|Next)W, and MODULEENTRY32 to map to MODULEENTRY32W (and FindWindow() to map to FindWindowW()). Thus, the szModule field is a wchar_t[] array instead of a char[] array, like you are expecting. std::cout does not have an overload of operator<< for wchar_t data, only char data, but it has an overload for void*, and a fixed array decays into a pointer that can then be assigned to void*. That is why your code is printing out the string data as a memory address - you are printing out the address of the szModule field rather than its content.

    You need to either:

    • use std::wcout instead, and preferably also explicitly use the W version of the API functions to match:

      #include <windows.h>
      #include <TlHelp32.h>
      #include <iostream>
      #include <string>
      
      int main() {
      
          MODULEENTRY32W me32;
          HWND hwnd = FindWindowW(0, L"Window Name");
          DWORD dwPID;
          GetWindowThreadProcessId(hwnd, &dwPID);
      
          HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
      
          me32.dwSize = sizeof(me32);
          if (Module32FirstW(hModuleSnap, &me32))
          {
              do
              {
                  std::wstring moduleName = me32.szModule;
                  std::wcout << moduleName << std::endl; // important line
              }
              while (Module32NextW(hModuleSnap, &me32));
          }
      
          return 0;
      }
      
    • explicitly use the A version of the API functions to match your use of std::cout:

      #include <windows.h>
      #include <TlHelp32.h>
      #include <iostream>
      #include <string>
      
      int main() {
      
          MODULEENTRY32A me32;
          HWND hwnd = FindWindow(0, L"Window Name");
          DWORD dwPID;
          GetWindowThreadProcessId(hwnd, &dwPID);
      
          HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
      
          me32.dwSize = sizeof(MODULEENTRY32A);
          if (Module32FirstA(hModuleSnap, &me32))
          {
              do
              {
                  std::string moduleName = me32.szModule;
                  std::cout << moduleName << std::endl; // important line
              }
              while (Module32NextA(hModuleSnap, &me32));
          }
      
          return 0;
      }