进程管理API
概述
进程是程序的一次执行实例,拥有独立的地址空间和系统资源。Windows提供了丰富的进程管理API,用于创建、控制和监视进程。
进程创建
CreateProcess - 创建新进程
CreateProcess函数
创建一个新进程及其主线程,新进程在调用进程的安全上下文中运行。
| C++ |
|---|
| BOOL CreateProcess(
LPCSTR lpApplicationName, // 可执行模块名
LPSTR lpCommandLine, // 命令行字符串
LPSECURITY_ATTRIBUTES lpProcessAttributes, // 进程安全属性
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程安全属性
BOOL bInheritHandles, // 是否继承句柄
DWORD dwCreationFlags, // 创建标志
LPVOID lpEnvironment, // 环境变量块
LPCSTR lpCurrentDirectory, // 当前目录
LPSTARTUPINFOA lpStartupInfo, // 启动信息
LPPROCESS_INFORMATION lpProcessInformation // 进程信息
);
|
创建标志:
| 标志 |
值 |
说明 |
CREATE_NEW_CONSOLE |
0x00000010 |
创建新控制台 |
CREATE_NO_WINDOW |
0x08000000 |
不创建窗口 |
CREATE_SUSPENDED |
0x00000004 |
创建后挂起主线程 |
CREATE_UNICODE_ENVIRONMENT |
0x00000400 |
使用Unicode环境块 |
DEBUG_PROCESS |
0x00000001 |
调试进程 |
DEBUG_ONLY_THIS_PROCESS |
0x00000002 |
只调试本进程 |
STARTUPINFO结构:
| C++ |
|---|
| typedef struct _STARTUPINFOA {
DWORD cb; // 结构大小
LPSTR lpReserved; // 保留
LPSTR lpDesktop; // 桌面名
LPSTR lpTitle; // 窗口标题
DWORD dwX; // 窗口X坐标
DWORD dwY; // 窗口Y坐标
DWORD dwXSize; // 窗口宽度
DWORD dwYSize; // 窗口高度
DWORD dwXCountChars; // 屏幕缓冲区宽度
DWORD dwYCountChars; // 屏幕缓冲区高度
DWORD dwFillAttribute; // 控制台填充属性
DWORD dwFlags; // 标志
WORD wShowWindow; // 显示窗口标志
WORD cbReserved2; // 保留
LPBYTE lpReserved2; // 保留
HANDLE hStdInput; // 标准输入句柄
HANDLE hStdOutput; // 标准输出句柄
HANDLE hStdError; // 标准错误句柄
} STARTUPINFOA;
|
PROCESS_INFORMATION结构:
| C++ |
|---|
| typedef struct _PROCESS_INFORMATION {
HANDLE hProcess; // 进程句柄
HANDLE hThread; // 主线程句柄
DWORD dwProcessId; // 进程ID
DWORD dwThreadId; // 主线程ID
} PROCESS_INFORMATION;
|
示例:
| C++ |
|---|
| STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
si.cb = sizeof(si);
// 创建进程
BOOL success = CreateProcess(
NULL, // 使用命令行中的模块名
"notepad.exe C:\\test.txt", // 命令行
NULL, // 默认进程安全属性
NULL, // 默认线程安全属性
FALSE, // 不继承句柄
0, // 默认创建标志
NULL, // 使用父进程环境
NULL, // 使用父进程当前目录
&si, // 启动信息
&pi // 进程信息
);
if (success) {
printf("Process created. PID: %d\n", pi.dwProcessId);
// 等待进程结束
WaitForSingleObject(pi.hProcess, INFINITE);
// 获取退出码
DWORD exitCode;
GetExitCodeProcess(pi.hProcess, &exitCode);
printf("Exit code: %d\n", exitCode);
// 关闭句柄
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
|
ShellExecute - 执行程序
| C++ |
|---|
| HINSTANCE ShellExecute(
HWND hwnd, // 父窗口句柄
LPCTSTR lpOperation, // 操作类型
LPCTSTR lpFile, // 文件或程序
LPCTSTR lpParameters, // 参数
LPCTSTR lpDirectory, // 工作目录
INT nShowCmd // 显示方式
);
|
操作类型:
- "open":打开文件或程序
- "print":打印文件
- "explore":浏览文件夹
- "runas":以管理员身份运行
示例:
| C++ |
|---|
| // 打开网页
ShellExecute(NULL, "open", "https://www.baidu.com", NULL, NULL, SW_SHOWNORMAL);
// 打开记事本
ShellExecute(NULL, "open", "notepad.exe", "C:\\test.txt", NULL, SW_SHOWNORMAL);
// 以管理员身份运行
ShellExecute(NULL, "runas", "cmd.exe", NULL, NULL, SW_SHOWNORMAL);
|
进程控制
OpenProcess - 打开进程
| C++ |
|---|
| HANDLE OpenProcess(
DWORD dwDesiredAccess, // 访问权限
BOOL bInheritHandle, // 继承标志
DWORD dwProcessId // 进程ID
);
|
访问权限:
| 权限 |
说明 |
PROCESS_ALL_ACCESS |
所有权限 |
PROCESS_TERMINATE |
终止进程 |
PROCESS_CREATE_THREAD |
在进程中创建线程 |
PROCESS_VM_OPERATION |
内存操作 |
PROCESS_VM_READ |
读取内存 |
PROCESS_VM_WRITE |
写入内存 |
PROCESS_QUERY_INFORMATION |
查询信息 |
SYNCHRONIZE |
等待进程结束 |
示例:
| C++ |
|---|
| HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 1234);
if (hProcess == NULL) {
printf("OpenProcess failed: %d\n", GetLastError());
}
|
TerminateProcess - 终止进程
TerminateProcess函数
强制终止进程,可能导致资源泄漏,不推荐使用。
| C++ |
|---|
| BOOL TerminateProcess(
HANDLE hProcess, // 进程句柄
UINT uExitCode // 退出代码
);
|
示例:
| C++ |
|---|
| HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
if (hProcess) {
TerminateProcess(hProcess, 1);
CloseHandle(hProcess);
}
|
GetExitCodeProcess - 获取进程退出码
| C++ |
|---|
| BOOL GetExitCodeProcess(
HANDLE hProcess, // 进程句柄
LPDWORD lpExitCode // 退出码
);
|
示例:
| C++ |
|---|
| DWORD exitCode;
GetExitCodeProcess(hProcess, &exitCode);
if (exitCode == STILL_ACTIVE) {
printf("Process is still running\n");
} else {
printf("Process exited with code: %d\n", exitCode);
}
|
进程等待
WaitForSingleObject - 等待单个对象
| C++ |
|---|
| DWORD WaitForSingleObject(
HANDLE hHandle, // 对象句柄
DWORD dwMilliseconds // 超时时间
);
|
返回值:
- WAIT_OBJECT_0:对象已触发
- WAIT_TIMEOUT:超时
- WAIT_FAILED:失败
- WAIT_ABANDONED:对象被放弃(仅用于互斥体)
示例:
| C++ |
|---|
| DWORD result = WaitForSingleObject(hProcess, 5000); // 等待5秒
switch (result) {
case WAIT_OBJECT_0:
printf("Process ended\n");
break;
case WAIT_TIMEOUT:
printf("Timeout\n");
break;
case WAIT_FAILED:
printf("Wait failed: %d\n", GetLastError());
break;
}
|
| C++ |
|---|
| DWORD WaitForMultipleObjects(
DWORD nCount, // 对象数量
const HANDLE *lpHandles, // 对象句柄数组
BOOL bWaitAll, // 是否等待所有对象
DWORD dwMilliseconds // 超时时间
);
|
示例:
| C++ |
|---|
| HANDLE hProcesses[2];
hProcesses[0] = OpenProcess(SYNCHRONIZE, FALSE, pid1);
hProcesses[1] = OpenProcess(SYNCHRONIZE, FALSE, pid2);
DWORD result = WaitForMultipleObjects(
2, // 2个进程
hProcesses, // 句柄数组
TRUE, // 等待所有进程
INFINITE // 无限等待
);
// 关闭句柄
for (int i = 0; i < 2; i++) {
CloseHandle(hProcesses[i]);
}
|
进程信息
GetCurrentProcess - 获取当前进程句柄
| C++ |
|---|
| HANDLE GetCurrentProcess();
|
返回值:返回当前进程的伪句柄(值为-1)
GetCurrentProcessId - 获取当前进程ID
| C++ |
|---|
| DWORD GetCurrentProcessId();
|
示例:
| C++ |
|---|
| printf("Current process ID: %d\n", GetCurrentProcessId());
|
GetProcessId - 从句柄获取进程ID
| C++ |
|---|
| DWORD GetProcessId(
HANDLE Process // 进程句柄
);
|
GetModuleFileName - 获取模块路径
| C++ |
|---|
| DWORD GetModuleFileName(
HMODULE hModule, // 模块句柄
LPSTR lpFilename, // 路径缓冲区
DWORD nSize // 缓冲区大小
);
|
示例:
| C++ |
|---|
| char path[MAX_PATH];
GetModuleFileName(NULL, path, MAX_PATH); // 获取当前进程路径
printf("Process path: %s\n", path);
|
GetCommandLine - 获取命令行
示例:
| C++ |
|---|
| printf("Command line: %s\n", GetCommandLine());
|
进程环境
GetEnvironmentStrings - 获取环境变量块
| C++ |
|---|
| LPCH GetEnvironmentStrings();
|
FreeEnvironmentStrings - 释放环境变量块
| C++ |
|---|
| BOOL FreeEnvironmentStrings(
LPCH lpszEnvironmentBlock
);
|
GetEnvironmentVariable - 获取环境变量
| C++ |
|---|
| DWORD GetEnvironmentVariable(
LPCTSTR lpName, // 变量名
LPTSTR lpBuffer, // 缓冲区
DWORD nSize // 缓冲区大小
);
|
示例:
| C++ |
|---|
| char path[MAX_PATH];
DWORD len = GetEnvironmentVariable("PATH", path, MAX_PATH);
if (len > 0) {
printf("PATH: %s\n", path);
}
|
SetEnvironmentVariable - 设置环境变量
| C++ |
|---|
| BOOL SetEnvironmentVariable(
LPCTSTR lpName, // 变量名
LPCTSTR lpValue // 变量值(NULL表示删除)
);
|
示例:
| C++ |
|---|
| SetEnvironmentVariable("MY_VAR", "Hello World");
SetEnvironmentVariable("MY_VAR", NULL); // 删除变量
|
进程优先级
GetPriorityClass - 获取优先级
| C++ |
|---|
| DWORD GetPriorityClass(
HANDLE hProcess
);
|
SetPriorityClass - 设置优先级
| C++ |
|---|
| BOOL SetPriorityClass(
HANDLE hProcess,
DWORD dwPriorityClass
);
|
优先级类:
| 优先级 |
值 |
说明 |
IDLE_PRIORITY_CLASS |
0x0040 |
空闲优先级 |
BELOW_NORMAL_PRIORITY_CLASS |
0x4000 |
低于标准 |
NORMAL_PRIORITY_CLASS |
0x0020 |
标准优先级 |
ABOVE_NORMAL_PRIORITY_CLASS |
0x8000 |
高于标准 |
HIGH_PRIORITY_CLASS |
0x0080 |
高优先级 |
REALTIME_PRIORITY_CLASS |
0x0100 |
实时优先级 |
示例:
| C++ |
|---|
| SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
|
实用示例
创建子进程并捕获输出
| C++ |
|---|
| #include <windows.h>
#include <stdio.h>
int main() {
SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
// 创建管道
HANDLE hReadPipe, hWritePipe;
CreatePipe(&hReadPipe, &hWritePipe, &sa, 0);
// 设置启动信息
STARTUPINFO si = {0};
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = hWritePipe;
si.hStdError = hWritePipe;
PROCESS_INFORMATION pi = {0};
// 创建进程
CreateProcess(
NULL,
"cmd.exe /c dir",
NULL, NULL, TRUE, 0, NULL, NULL,
&si, &pi
);
// 关闭写入端
CloseHandle(hWritePipe);
// 读取输出
char buffer[4096];
DWORD bytesRead;
while (ReadFile(hReadPipe, buffer, sizeof(buffer) - 1, &bytesRead, NULL)) {
buffer[bytesRead] = '\0';
printf("%s", buffer);
}
// 清理
CloseHandle(hReadPipe);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
|
检查进程是否存在
| C++ |
|---|
| BOOL IsProcessRunning(DWORD pid) {
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (hProcess == NULL) {
return FALSE;
}
DWORD exitCode;
GetExitCodeProcess(hProcess, &exitCode);
CloseHandle(hProcess);
return (exitCode == STILL_ACTIVE);
}
|
参考资料