首页 > 解决方案 > 转换和打印进程的模块名称

问题描述

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

但是在打印 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 在他们的示例中使用以下内容来转换和打印模块名称:

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

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

那么如何转换和保存字符串me32呢?

标签: c++winapi

解决方案


您的项目正在使用UNICODE定义进行编译(很明显,您可以将宽字符串传递给FindWindow())。这导致Module32(First|Next)映射到Module32(First|Next)W,并MODULEENTRY32映射到MODULEENTRY32W(和FindWindow()映射到FindWindowW())。因此,该szModule字段是一个wchar_t[]数组而不是一个char[]数组,就像您所期望的那样。 std::cout没有operator<<for wchar_tdata 的重载,只有chardata ,但是它有 for 的重载void*,并且一个固定的数组衰减为一个指针,然后可以分配给void*。这就是为什么您的代码将字符串数据打印为内存地址的原因 - 您打印的是字段的地址szModule而不是其内容

您需要:

  • 改用std::wcout,最好也显式使用WAPI 函数的版本来匹配:

    #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;
    }
    
  • 显式使用AAPI 函数的版本来匹配您的使用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;
    }
    

推荐阅读