Process32FirstW

基本概念

Process32FirstWWindows系统Tool Help Library(工具帮助库)中用于枚举进程信息的宽字符(Unicode)版本起始函数(Process32FirstANSI版本)。它的核心作用是从通过CreateToolhelp32Snapshot创建的 “进程快照” 中,提取第一个进程的详细信息(如进程 ID、父进程 ID、可执行文件路径等),是遍历系统所有进程的 “起点”,通常与Process32NextW配合使用以完成全部进程的枚举。

基本语法

1
2
3
4
5
6
7
8
9
BOOL Process32FirstW(
[in] HANDLE hSnapshot, // 进程快照句柄(由CreateToolhelp32Snapshot返回)
[in, out] LPPROCESSENTRY32W lppe // 指向PROCESSENTRY32W结构体的指针,用于接收进程信息
);

BOOL Process32First(
[in] HANDLE hSnapshot,
[in, out] LPPROCESSENTRY32 lppe
);

LPPROCESSENTRY32W

1
2
3
4
5
6
7
8
9
10
11
12
typedef struct tagPROCESSENTRY32W {
DWORD dwSize; // 结构体大小(必须初始化)
DWORD cntUsage; // 已过时(进程引用计数,始终为0)
DWORD th32ProcessID; // 进程ID(PID,唯一标识)
ULONG_PTR th32DefaultHeapID; // 已过时(默认堆ID,无实际意义)
DWORD th32ModuleID; // 进程的主模块ID(通常为进程自身)
DWORD cntThreads; // 进程包含的线程数量
DWORD th32ParentProcessID; // 父进程ID(PPID,创建该进程的进程)
LONG pcPriClassBase; // 进程的基本优先级(数值越低优先级越高)
DWORD dwFlags; // 已过时(进程标志,始终为0)
WCHAR szExeFile[MAX_PATH]; // 进程可执行文件名(含路径,宽字符字符串)
} PROCESSENTRY32W, *PPROCESSENTRY32W;

返回值

成功:返回TRUE,此lppe结构体已填充第一个进程的详细信息。
失败:返回FALSE,可通过GetLastError()查看具体错误原因。

Process32NextW

基本概念

Process32NextWWindows系统Tool Help Library中用于 枚举进程信息的宽字符(Unicode)版本后续函数(Process32NextANSI版本)。它与Process32FirstW配合使用,在获取第一个进程信息后,依次提取进程快照中后续所有进程的详细数据,直至完成系统中所有进程的遍历。

基本语法

1
2
3
4
5
6
7
8
9
BOOL Process32NextW(
[in] HANDLE hSnapshot,// 进程快照句柄(与Process32FirstW共用)
[out] LPPROCESSENTRY32W lppe //指向PROCESSENTRY32W结构体的指针,接收下一个进程信息
);

BOOL Process32Next(
[in] HANDLE hSnapshot,
[out] LPPROCESSENTRY32 lppe
);

返回值

成功:返回TRUElppe结构体中已填充下一个进程的信息。
失败:返回FALSE,通过GetLastError()判断原因:
若返回ERROR_NO_MORE_FILES:表示所有进程已枚举完毕(正常结束)。
其他错误码(如ERROR_INVALID_PARAMETERERROR_ACCESS_DENIED):表示参数无效、权限不足或快照句柄错误。

简单示例

枚举所有进程,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

int main() {
// 1. 创建进程快照(捕获所有进程)
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
printf("创建快照失败!错误码:%lu\n", GetLastError());
return 1;
}

// 2. 初始化进程信息结构体(必须设置dwSize)
PROCESSENTRY32W pe32;
pe32.dwSize = sizeof(PROCESSENTRY32W);

// 3. 获取第一个进程信息
if (!Process32FirstW(hSnapshot, &pe32)) {
printf("获取第一个进程失败!错误码:%lu\n", GetLastError());
CloseHandle(hSnapshot); // 释放资源
return 1;
}

// 4. 遍历所有进程(Process32NextW返回FALSE时结束)
printf("=== 系统进程列表(PID | 父PID | 进程名) ===\n");
do {
// 打印进程信息(%ls用于输出宽字符字符串)
wprintf(L"%-6lu | %-6lu | %ls\n",
pe32.th32ProcessID,
pe32.th32ParentProcessID,
pe32.szExeFile);
} while (Process32NextW(hSnapshot, &pe32));

// 5. 检查是否因“枚举完毕”而退出(正常情况)
DWORD lastError = GetLastError();
if (lastError != ERROR_NO_MORE_FILES) {
printf("枚举进程失败!错误码:%lu\n", lastError);
}

// 6. 关闭快照句柄(必须释放资源)
CloseHandle(hSnapshot);
return 0;
}