创建进程、获取进程相关信息、获取启动参数
1.父进程与子进程
如果一个进程创建了另外一个进程,那么被创建的进程称为子进程,创建者称为子进程的父进程。
2.启动参数
进程被创建后,可以使用GetCommandLine、GetStartupInfo 函数获取启动参数、启动信息。执行程序时,在命令行中输入的参数是程序的启动参数。以 main 函数作为入口函数的序动参数即是main函数的参数。
3,进程句柄和进程标识
如果需要知道自己的句柄可以使用 GetCurrentProcess 和GetCurrentProcessld 函数获取自己的句柄和PID。可以使用GetPriorityClass 、GetProcessTimes 、GetProcessVersion GetProcessWorkingSetSize函数获取进程的相关信息。
HANDLE WINAPI GetCurrentProcess(void);
1、返回当前进程的伪句柄(始终返回-1)
2、-1表示当前进程的伪句柄
3、-2表示当前线程的伪句柄,可以用GetCurrentThread试一试(始终返回-2)
4、不要直接使用-1这个值,为了将来的兼容性请使用GetCurrentProcess
5、伪句柄不被继承,想想如果可以继承,那么-1代表什么(父进程的伪句柄?子进程的伪句柄?)
6、可以通过DuplicateHandle和OpenProcess获取当前进程真实句柄
7、伪句柄可以在当前进程中使用,如果需要跨进程通信,那么必须拿出自己真实句柄了
8、伪句柄不需要CloseHandle,即使调用CloseHandle表现为不起作用
9、如果该通过DuplicateHandle和OpenProcess获取当前进程真实句柄后,不在使用时需要CloseHandle,防止句柄泄露
DWORD GetCurrentProcessId();
返回值
返回值是调用进程的进程标识符。
备注
在进程终止之前,进程标识符会在整个系统中唯一标识进程。
如果进程知道其他进程的标识 (PID),还可以通过 OpenProcess 函数取进程的柄,也可以通过 GetProcessId 通过柄取 PID,在具有权限的情况下,也可以通过相关函数获取其他进程的信息。
4,退出和终止进程
进程的主线程执行完成,则进程自动退出。如果要立即退出运行可以使用 ExitProcess 函数如果需要终止其他进程,可以使用 TerminateProcess。
5.关键API
创建进程最常使用到的 API 函数 CreateProcess ,另外还有 CreateProcessAsUserCreateProcessWithLogonW,CreateProcessWithTokenW 等函数,这几个函数除了可以创建线程,还可以指定特殊的安全属性。WinExec 函数的功能是执行程序,也可以创建进程,但是只能设定几个简单的参数,功能比 CreateProcess 简单。
(1) CreateProcess
CreateProcess 函数的功能是创建进程,函数原型如下
BOOl CreateProcess(
LPCTSTR lpApplicationName,
LPTSTR IpCommandLine
LPSECURITY ATTRIBUTESlpProcessAttributes
LPSECURITY ATTRIBUTESlpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags
LPVOID lpEnvironment.
LPCTSTR 1pCurrentDirectory.
LPSTARTUPINFO lpStartupInfo,
LPPROCESS INFORMATION lpProcessInformation
};
参数说明:
IpApplicationName:输入参数,指向启动进程的exe 文件,可以为 NULL,如果为 NULL,则lpCommandLine 参数不能为NULL
lpCommandLine:输入参数,启动进程的命令行第一个空格标识符前的字符为启动进行的exe此后紧接启动参数。
lpProcessAttributes:输入参数指向SECURITY_ATTRIBUTES 结构变量为进程的安全属性可设置为 NULL,使用默认安全属性。
lpThreadAttributes:输入参数,进程柄是否可被子进程继承,设置为 NULL,则不会继承。
bInheritHandles:输入参数,与子进程的句柄继承关系。
dwCreationFlags:输入参数,进程的创建标志和优先级控制。比如CREATE NEWCONSOLE会使新建的控制台程序具有一个新控制台;DEBUG PROCESS 标志会使父进程具有调试权限,其子进程会产生调试事件。
lpEnvironment:输入参数,指向新进程的环境变量块,如果设置为 NULL,则使用父进程的环境变量。
lpCurrentDirectory:输入参数,指定创建后新进程的当前目录,如果为NULL,则为父进行的当前目录。
lpStartupInfo:输入参数,指向 STARTUPINFO 数据结构变量,设定启动信息,可以为NULL。lpProcessInformation:输出参数,指向 PPROCESSINFORMATION 结构的变量,返回被创建的进程的信息。
说明
lpApplicationName 或lpCommandLine 参数指明的exe 文件路径可以是绝对路径,也可以是相对路径。如果不包括路径而只是文件名,系统将按以下顺序找文件:父进程的当前路径、系统路径Windows 路径、PATH环境变量中包含的路径。文件名可以不包含exe 扩展名。命令行参数以空格为分隔符,如果参数内存在空格(比如文件路中有空格则将参数置于引号中。
具体实例代码:
/*
创建进程、获取进程相关信息、获取启动参数
/*
// 头文件
#include <windows.h>
#include <stdio.h>
int main()
CreateChildProcess("Child.exe abc 123");
//* DWORD CreateChildProcess(LPSTR szChildProcessCmd)
//* 功能:演示创建子进程
//* 参数: LPSTR szChildProcessCmd 启动子程序的命令行
//* 返回值:成功返回 0,失败返回 1
DWORD CreateChildProcess(LPSTR szChildProcessCmd)
STARTUPINFO s1;
PROCESS_INFORMATION P1:
//将启动信息结构清零
ZeroMemory( &si, sizeof(si) );
// 设置结构大小,cb 属性应为结构的大小
si.cb = sizeof(si);
//将进程信息结构清零
ZeroMemory( &pi, sizeof(pi) );
// 创建子进程,并判断是否成功
if( !CreateProcess( NULL, // 使用命令行
szChildProcessCmd, // 命令行
NULL, //不继承进程句柄
NULL,//不继承线程句柄
FALSE, //不继承句柄
0, //没有创建标志
NULL,//使用父进程环境变量
NULL,//使用父进程目录作为当前目录
&si,// STARTUPINFO 结构
&pi )// PROCESS INFORMATION 保存相关信息
)
{
//创建失败
printf( "CreateProcess failed (d),\n”, GetLastError() );
return 1;
}
//在创建成功后父进程也可直接退出,这里等待子进程执行结束
//等待子进程结束
//使用到了通过 PROCESS_INFORMATION 返回的相关信息,hProcess 为子进程句柄
// 父进程也可以不等待子进程运行完成而直接退出
WaitForSingleObject( pi.hProcess, INFINITE );
//关闭进程句柄和线程句柄
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
return 0;
}
需要注意的是,在本实例中,为 CreateProcess 设置了尽可能简单的参数,使用 pi变量获取返回的子进程信息并使用了进程句柄等信息。
由于在命令行中直接使用文件名,在运行时,需将 Child.exe 与本实例程序放置在同一目录下。