跟着 rkvir 老师学学今天的知识,今天的课程是 《Windows系统编程》——进程基础与相关结构

课堂笔记

系统管理进程所需的两个基本部分

  1. 一个管理用的内核对象(进程句柄)
  2. 一个包含代码数据的地址空间。

创建进程的实现

CreateProcess

说明

宏定义实现,根据字符集选择调用 CreateProcessA 或者是 CreateProcessW,实现了 ANSI 版本的创建和宽字符版的进程创建,返回一个进程句柄。

参数
  1. lpApplicationName:想要执行的可执行文件的路径
  2. lpCommand:命令行参数,可以传 NULL 表示没有参数
  3. lpProcessAttributes:进程安全属性,传 NULL 表示默认
  4. lpThreadAttributes:线程安全属性,传 NULL 表示默认
  5. bInheritHandles:表示句柄是否可以被继承
  6. dwCreationFlags:创建的新进程的标志
  7. lpEnvironment:环境变量
  8. lpCurrentDirectory:指定当前目录
  9. lpStartInfo:指定启动信息
  10. lpProcessInformation:指定进程信息
例子

启动桌面上的一个程序:

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
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
int main()
{
STARTUPINFO StartupInfo;
StartupInfo = { sizeof(StartupInfo) };//初始化
PROCESS_INFORMATION ProcessInformation;
BOOL bRet=CreateProcess(L"C:\\Users\\xia0ji233\\Desktop\\Processor.exe",
NULL,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&StartupInfo,
&ProcessInformation
);
if (bRet)
{
printf("Create Success\n");
printf("%d\n", ProcessInformation.hProcess);
printf("%d\n", ProcessInformation.hThread);
printf("%d\n", ProcessInformation.dwProcessId);
printf("%d\n", ProcessInformation.dwThreadId);
}
else
{
printf("Create Error\n");
}

}

运行结果

进程退出

ExitProcess

退出当前进程,内部参数表示退出的一个返回值,0表示正常退出。

TerminateProcess

退出指定进程,第一个参数为进程的进程句柄,第二个参数表示退出的返回值。

如果是自己创建的进程,我们可以直接从进程信息,也就是前面 CreateProcess 给我们返回的对象中直接拿到进程句柄,如果不是我们创建的我们需要去打开它的一个进程句柄。

OpenProcess

根据 pid 返回一个进程句柄,第一个参数是打开的进程的权限,第二个参数是是否可以被继承,第三个参数是进程的 pid。

一般情况下使用 PROCESS_ALL_ACCESS 获取进程的完整权限。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
int main()
{
int pid;
printf("input a pid:");
scanf("%d", &pid);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hProcess != INVALID_HANDLE_VALUE)
{
TerminateProcess(hProcess, 0);
printf("kill success");
}
}

遍历进程,线程

遍历进程

我们需要用到 CreateToolhelp32Snapshot 函数,它被包含在 TlHelp32.h 头文件当中,它的作用就是拍摄一个快照,通过第一个参数选择堆,进程,线程,模块等信息,可以查看宏定义:

1
2
3
4
5
6
7
#define TH32CS_SNAPHEAPLIST 0x00000001
#define TH32CS_SNAPPROCESS 0x00000002
#define TH32CS_SNAPTHREAD 0x00000004
#define TH32CS_SNAPMODULE 0x00000008
#define TH32CS_SNAPMODULE32 0x00000010
#define TH32CS_SNAPALL (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE)
#define TH32CS_INHERIT 0x80000000

返回值是一个快照句柄。

不论是遍历什么内容,我们都用 Process32First 函数去获得信息。第一个参数是刚刚函数的返回值类型,也就是快照句柄,第二个参数用于接收结果,类型为 PROCESSENTRY32。

同样,这个结构体也要初始化。

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
int main()
{
HANDLE hSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 pe32;
pe32 = { sizeof(pe32) };

BOOL ret=Process32First(hSnap, &pe32);
while (ret)
{
wprintf(L"PROCESS_NAME:%s\n", pe32.szExeFile);
ret=Process32Next(hSnap,&pe32);
}
}

运行结果