CreateProcess
● CreateProcess 创建进程函数
○ 当CreateProcess被一个线程调用时,系统会创建一个进程内核对象,进程内核对象并不代表进程本身,它是操作系统,用来管理这个进程的数据结构,该数据结构中有一个使用计数,会在进程被创建时设置为1,然后系统位新进程创建一个虚拟地址空间,讲所需的代码一集数据加载到进程地址 空间之后,系统为新进程创建一个线程内核对象,主线程最终会调用我们的main函数。如果系统成功创建了新进程和主线程,函数会返回true.
○ 1.操作系统创建内核对象
当我们进行进程创建的时候
操作系统会帮我们创建一个内核对象
内核对象不代码我们当前进程的本身
操作系统创建内核对象是方便管理我们的进程
内核对象是一个结构体
○ 程序运行不只会创建进程线程 4件事情,还会加载DLL但是这个函数只要前面4件事情成功就会提示true 不会管DLL是否加载成功的
1 BOOL WINAPI CreateProcess( 2 _In_opt_ LPCTSTR lpApplicationName, 3 _Inout_opt_ LPTSTR lpCommandLine, 4 _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 5 _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 6 _In_ BOOL bInheritHandles, 7 _In_ DWORD dwCreationFlags, 8 _In_opt_ LPVOID lpEnvironment, 9 _In_opt_ LPCTSTR lpCurrentDirectory, 10 _In_ LPSTARTUPINFO lpStartupInfo, 11 _Out_ LPPROCESS_INFORMATION lpProcessInformation 12 );
● pszApplicationName
○ 指定新进程要使用的知兴替文件的名称
EXE文件就是可执行文件
DLL也是可执行文件
○ 当在pszApplicationName中传一个文件路径时,如果给的是一个相对路径,那么他只会在当前目录下进行查找,当这个值不为NULL时,pszCommandLine会被作为命令行参数传递
● pszCommandLine
○ 传递新进程的命令行字符串
如果pszApplication 为 NULL,我们可以在pszCommandLine中传一个文件的路径,如果我们传递一个相对路径,他会按照一下程序搜索
1.所在目录
2.当前目录
3.Windows系统目录(System32目录)
4.Windows目录
5.Path环境变量中列出的目录
○ pszCommandLine参数还有一个需要注意的地方,CreateProcess内部会修改这个参数,所以我们不应该传递一个常量指针
● psaProces
○ 设置进程内核对象的安全属性
● psaThread
○ 设置主线程对象程序的安全性
● blnheritHandles
○ 是否被继承
以上三个参数主要控制我们启动的子进程是否有继承的权限,指的是对内核对象的继承权限
这里就不讲了 全部设置位 NULL NULL FALSE
● fdwCreate
○ 标志位 标志很多
○ 进程创建方式标志
● CREATE_NO_WINDOW
○ 标志指示系统不要为应用程序创建任何控制台窗口,可以使用这个 标志来执行没有用户界面的控制台应用程序.
● pvEnvironment
○ 被我们新进程是否来设置一些环境变量
○ pvEnvironment 参数指向一个内存块,其中包含了新进程要使用的环境字符串。大多数时候,为这个参数传入的值都是NULL,这将导致子进程集成父进程使用的一组环境变量字符串。另外,还可以使用GetEnvironmentStrings函数
● pszCurDir
○ pszCurDir参数允父进程设置子进程的当前驱动器的目录.如果这个参数位NULL,则新进程的工作目录与生成新进程的应用程序一样。
● pslStartInfo
○ 此结构体一定要清零,否则成员间包含主调线程堆栈上的垃圾数据
1 typedef struct _STARTUPINFO 2 { 3 DWORD cb; //初始化sizeof(STARTUPINFO) 4 PSTR lpReserved; //保留,必须初始化位NULL 5 PSTR lpDesktop; //启动应用程序的桌面 6 PSTR lpTitle; //控制台不可用,指定控制台标题 7 DWORD dwX; //屏幕的位置 8 DWORD dwY; //屏幕的位置 9 DWORD dwXSize; //屏幕的宽度 10 DWORD dwYSize; //屏幕的高度 11 DWORD dwXCountChars; //控制台不可用,控制台的高度 12 DWORD dwYCountChars; //控制台不可用,控制台的高度 13 DWORD dwFlags; //组合值 14 WORD wShowWIndow; //窗口如何显示 15 WORD cbReserved2; //保留 16 PBYTE lpReserved2; //保留 17 HANDLE hStdInput; //设置标准输入 18 HANDLE hStdOutput; //设置标准输出 19 HANDLE hStdError; //设置标准错误输出 20 }STARTUPINFO, *LPSTARTUPINOF;
Flags的取值
STARTF _USESIZE 使用dwXSize和dwYSize成员
STARTF _USESHOWWINDOWS 使用wShowWindow成员
STARTF _USEPOSITION 使用dwX and dwY 成员
STARTF _USERCOUNTCHARS 使用dwXCountChars 和dwYCountChars成员
STARTF _USEFILLATTRIBUTE 使用dwFillAttnbute成员
STARTF _USESTDHANDLES 使用nStdInput,hStdOutput和hStdError成员
STARTF _RUNFULLSCREEN 使x86计算机上运行的一个控制台应用程序以全屏模式启动
STARTF _FORCEOFFFEEDBACK 使用hStdInput, StdOutput 和hStdError成员
STARTF _FORCEONFEEDBACK 使x86计算机上运行的一个控制台应用程序以全屏模式启动
STARTF _PREVENTPINNING 窗口无法被固定在任务栏上
STARTF _TITLEISAPPID 设置任务栏和开始菜单的状态
● ppiProcInfo
1 typeedf struct _PROCESS_INFO 2 3 { 4 5 HANDLE hProcess; 6 HANDLE hThread; 7 DWORD dwProcessId; 8 DWORD dwThreadId; 9 } PROCESS_INFORMATION;