跳转至

获取游戏的进程标识符

要读写游戏内存,你需要它的进程标识符(PID),一个唯一标识活动进程的数字。如果游戏有可见窗口,你可以通过调用 GetWindowThreadProcessId() 获取创建该窗口的进程的 PID。这个函数把窗口句柄作为第一个参数,把 PID 输出到第二个参数。你可以通过把窗口标题(任务栏上的文本)作为第二个参数传给 FindWindow() 来找到窗口句柄,如清单 6-1 所示。

HWND myWindow =
    FindWindow(NULL, "Title of the game window 
here");
DWORD PID;
GetWindowThreadProcessId(myWindow, &PID);

清单 6-1:获取窗口句柄以获得 PID

有了窗口句柄,你只需创建一个存储 PID 的地方并调用 GetWindowThreadProcessId(),如这个示例所示。

如果游戏没有窗口,或者窗口名称不可预测,你可以通过枚举所有进程并查找游戏二进制名称来找到游戏的 PID。清单 6-2 使用 tlhelp32.h 中的 API 函数 CreateToolhelp32Snapshot()、Process32First() 和 Process32Next() 做到这一点。

#include <tlhelp32.h>
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
HANDLE snapshot =
    CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 
NULL);
if (Process32First(snapshot, &entry) == TRUE) {
    while (Process32Next(snapshot, &entry) == 
TRUE) {
        wstring binPath = entry.szExeFile;
        if (binPath.find(L"game.exe") != 
wstring::npos) {
            printf("game pid is %d\n", 
entry.th32ProcessID);
            break;
        }
    }
}
CloseHandle(snapshot);

清单 6-2:在没有窗口名称的情况下获取游戏的 PID

清单 6-2 看起来可能比清单 6-1 复杂一些,但在所有这些代码之下,这个函数实际上就像一个典型的 for (迭代器; 比较器;增量) 循环。CreateToolhelp32Snapshot() 函数获取一个名为 snapshot 的进程列表,entry 是该列表上的迭代器。Process32First() 返回的值初始化迭代器,而 Process32Next() 递增它。最后,Process32Next() 的布尔返回值是比较器。这段代码只是遍历每个运行进程的快照,查找二进制路径包含文本 game.exe 的进程,并打印它的 PID。