跳转至

进程管理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++
1
2
3
4
5
6
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++
1
2
3
4
5
6
7
8
HINSTANCE ShellExecute(
    HWND    hwnd,          // 父窗口句柄
    LPCTSTR lpOperation,   // 操作类型
    LPCTSTR lpFile,        // 文件或程序
    LPCTSTR lpParameters,  // 参数
    LPCTSTR lpDirectory,   // 工作目录
    INT     nShowCmd       // 显示方式
);

操作类型: - "open":打开文件或程序 - "print":打印文件 - "explore":浏览文件夹 - "runas":以管理员身份运行

示例

C++
1
2
3
4
5
6
7
8
// 打开网页
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++
1
2
3
4
5
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++
1
2
3
4
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 1234);
if (hProcess == NULL) {
    printf("OpenProcess failed: %d\n", GetLastError());
}

TerminateProcess - 终止进程

TerminateProcess函数

强制终止进程,可能导致资源泄漏,不推荐使用。

C++
1
2
3
4
BOOL TerminateProcess(
    HANDLE hProcess,   // 进程句柄
    UINT   uExitCode   // 退出代码
);

示例

C++
1
2
3
4
5
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
if (hProcess) {
    TerminateProcess(hProcess, 1);
    CloseHandle(hProcess);
}

GetExitCodeProcess - 获取进程退出码

C++
1
2
3
4
BOOL GetExitCodeProcess(
    HANDLE  hProcess,    // 进程句柄
    LPDWORD lpExitCode   // 退出码
);

示例

C++
1
2
3
4
5
6
7
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++
1
2
3
4
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;
}

WaitForMultipleObjects - 等待多个对象

C++
1
2
3
4
5
6
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++
1
2
3
DWORD GetProcessId(
    HANDLE Process  // 进程句柄
);

GetModuleFileName - 获取模块路径

C++
1
2
3
4
5
DWORD GetModuleFileName(
    HMODULE hModule,    // 模块句柄
    LPSTR   lpFilename, // 路径缓冲区
    DWORD   nSize       // 缓冲区大小
);

示例

C++
1
2
3
char path[MAX_PATH];
GetModuleFileName(NULL, path, MAX_PATH);  // 获取当前进程路径
printf("Process path: %s\n", path);

GetCommandLine - 获取命令行

C++
LPSTR GetCommandLine();

示例

C++
printf("Command line: %s\n", GetCommandLine());

进程环境

GetEnvironmentStrings - 获取环境变量块

C++
LPCH GetEnvironmentStrings();

FreeEnvironmentStrings - 释放环境变量块

C++
1
2
3
BOOL FreeEnvironmentStrings(
    LPCH lpszEnvironmentBlock
);

GetEnvironmentVariable - 获取环境变量

C++
1
2
3
4
5
DWORD GetEnvironmentVariable(
    LPCTSTR lpName,    // 变量名
    LPTSTR  lpBuffer,  // 缓冲区
    DWORD   nSize      // 缓冲区大小
);

示例

C++
1
2
3
4
5
char path[MAX_PATH];
DWORD len = GetEnvironmentVariable("PATH", path, MAX_PATH);
if (len > 0) {
    printf("PATH: %s\n", path);
}

SetEnvironmentVariable - 设置环境变量

C++
1
2
3
4
BOOL SetEnvironmentVariable(
    LPCTSTR lpName,  // 变量名
    LPCTSTR lpValue  // 变量值(NULL表示删除)
);

示例

C++
SetEnvironmentVariable("MY_VAR", "Hello World");
SetEnvironmentVariable("MY_VAR", NULL);  // 删除变量

进程优先级

GetPriorityClass - 获取优先级

C++
1
2
3
DWORD GetPriorityClass(
    HANDLE hProcess
);

SetPriorityClass - 设置优先级

C++
1
2
3
4
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);
}

参考资料