跟着 rkvir 老师学学今天的知识,今天的课程是 《Windows系统编程》——进程基础与相关结构
课堂笔记
系统管理进程所需的两个基本部分
- 一个管理用的内核对象(进程句柄)
- 一个包含代码数据的地址空间。
创建进程的实现
CreateProcess
说明
宏定义实现,根据字符集选择调用 CreateProcessA 或者是 CreateProcessW,实现了 ANSI 版本的创建和宽字符版的进程创建,返回一个进程句柄。
参数
- lpApplicationName:想要执行的可执行文件的路径
- lpCommand:命令行参数,可以传 NULL 表示没有参数
- lpProcessAttributes:进程安全属性,传 NULL 表示默认
- lpThreadAttributes:线程安全属性,传 NULL 表示默认
- bInheritHandles:表示句柄是否可以被继承
- dwCreationFlags:创建的新进程的标志
- lpEnvironment:环境变量
- lpCurrentDirectory:指定当前目录
- lpStartInfo:指定启动信息
- 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); } }
|
运行结果