BOOL WINAPI CreateProcess(
_In_opt_ LPCTSTR lpApplicationName,
_Inout_opt_ LPTSTR lpCommandLine, //是一个字符串,系统有可能改写,所以不能为常量
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCTSTR lpCurrentDirectory,
_In_ LPSTARTUPINFO lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation
);
lpApplicationName参数可以使用NULL,在这种情况下,lpCommandLine参数的第一个字符,必须是一个空白字符。如果可执行文件的命名中,包含空格,那么使用引用字符串来表示文件名的结束和参数的开始:否则,文件名就不明确。
也就是说lpApplicationName可以为NULL,也可以传递一个常量。但是lpCommandLine需要开辟一个内存,把参数名传递进去
TCHAR CommandLine[200] = L"D:/wxf/CreateProcessDetail.exe";,然后把lpCommandLine替换成CommandLine比较好
lpProcessAttributes进程的安全描述符,参见MSDN
lpThreadAttributes线程的安全描述符,参见MSDN
dwCreationFlags 上节讲过,控制优先级和如何创建进程
lpStartupInfo 是一个结构体,一个指向STARTUPINFO或者STARTUPINFOEX结构的指针。如果要设置扩展属性,那么在dwCreateFlags标志中,应该包含EXTENED_STARTUPINFI_PRESENT标志
typedef struct _STARTUPINFO {
DWORD cb; //结构体的大小
LPTSTR lpReserved;
LPTSTR lpDesktop; //此进程归哪个桌面
LPTSTR lpTitle; //进程的标题
DWORD dwX; //窗口位置大小
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;//对于控制台程序来说,一行有几个字符
DWORD dwYCountChars; //有多少行
DWORD dwFillAttribute;//填充属性 ,背景色和字体颜色,对于控制台程序来说
DWORD dwFlags; //窗口大小
WORD wShowWindow; //表示窗口是否显示
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} STARTUPINFO, *LPSTARTUPINFO;
进程内核对象的生命周期,一定比进程生命周期长,进程没有退出,代表进程的进程内核对象一定不会被销毁!!!
当进程退出后,也就是说,进程消失时候,进程内核对象对象才有可能被销毁。那么什么时候销毁这个进程内核对象呢?当进程内核对象的引用计数为0时,销毁进程内核对象。当进程退出的时候,进程内核对象的状态会发生变化,我们把进程退出后,进程内核对象的状态叫做激发态,如果进程在运行,那么代表进程的内核对象处于非激发态,此时,如果有类似WaitForSingleObject函数会被阻塞,直到进程退出,进程内核对象处于激发态。#include<windows.h>
#include<tchar.h>
int _tmain()
{
STARTUPINFO info;
ZeroMemory(&info, sizeof(info));
info.cb = sizeof(info);
PROCESS_INFORMATION si;
info.dwFlags = STARTF_RUNFULLSCREEN;
info.wShowWindow = 1;
_tprintf(L"CreateProcess\n", GetLastError());
// TCHAR CommandLine[200] = L"H:\\win32\\GetVesion\\Debug\\GetVesion.exe";
TCHAR CommandLine[200] = L"D:/wxf/CreateProcessDetail.exe 123";
if (!CreateProcess(NULL, CommandLine, NULL, NULL, FALSE,
CREATE_NEW_CONSOLE, NULL, NULL, &info, &si))
{
_tprintf(L"CreateProcess Failed=%d!\n", GetLastError());
_gettchar();
return 0;
}
_tprintf(L"wating for chil_process Exit\n");
WaitForSingleObject(si.hProcess, INFINITE);
//这个函数回阻塞程序允许,只有当si.hProcess进程推出后,这个函数才返回
_tprintf(L"Child_process Exit!\n");
CloseHandle(si.hProcess);//直到这个函数被调用,代表这个子进程的内核对象,才有可能被销毁
_gettchar();
return 0;
}