【问题标题】:Converting and printing the module names of a process [duplicate]转换和打印进程的模块名称[重复]
【发布时间】:2019-11-02 17:02:50
【问题描述】:

我正在尝试打印并保存进程的模块名称。

但是在打印 char 数组时,我得到了一些看起来像地址的东西。

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

在我的例子中,每个模块的输出是00AFF53C

me32.szModule 将模块的名称保存为 char 数组。

Microsoft 在their example 中使用以下内容来转换和打印模块名称:

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

但我认为你只能用它来打印字符串。

那么如何转换并保存me32中的字符串呢?

【问题讨论】:

    标签: c++ winapi


    【解决方案1】:

    您的项目正在编译时定义了UNICODE(很明显,您可以将宽字符串传递给FindWindow())。这导致Module32(First|Next) 映射到Module32(First|Next)WMODULEENTRY32 映射到MODULEENTRY32W(和FindWindow() 映射到FindWindowW())。因此,szModule 字段是 wchar_t[] 数组,而不是 char[] 数组,正如您所期望的那样。 std::coutwchar_t 数据没有operator&lt;&lt; 的重载,只有char 数据,但它对void* 有重载,固定数组衰减为一个指针,然后可以分配给@987654337 @。这就是为什么您的代码将字符串数据打印为内存地址的原因 - 您打印的是szModule 字段的地址,而不是它的内容

    您需要:

    • 改用std::wcout,最好也明确地使用API​​函数的W版本来匹配:

      #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;
      }
      
    • 明确使用A 版本的API 函数来匹配您对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;
      }
      

    【讨论】:

      【解决方案2】:

      如果根据Microsoft's documentation 定义了_UNICODE,则_tprintf()wprintf()typedef

      看看std::wcout

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多