获取游戏的进程标识符¶
要读写游戏内存,你需要它的进程标识符(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。