CreateProcess函数

调用CreateProcess函数来创建一个进程:

  1. 一个线程调用CreateProcess时,系统将创建一个进程内核对象,其初始使用计数为1.进程内核对象不是进程本身,而是操作系统用来管理这个进程的一个小型数据结构——可以把进程内核对象想象成由进程统计信息构成的一个小型数据结构。然后,系统为新进程创建一个虚拟地址空间,并将可执行文件(和所有必要的DLL)的代码及数据加载到进程的地址空间
  2. 然后,系统为新进程的主线程创建一个线程内核对象(其使用计数为1)。和进程内核对象一样,线程内核对象也是一个小型数据结构,操作系统用它来管理这个线程。这个主线程一开始就会执行C/C++运行时的启动例程,它是由链接器设为应用程序入口的,最终会调用应用程序WinMain,wWinMain、main或wmain函数。如果系统成功创建了新进程和主线程,CreateProcess将返回TRUE
BOOL CreateProcess(LPCTSTR lpApplicationName,
                   LPTSTR lpCommandLine,
                   LPSECURITY_ATTRIBUTES lpProcessAttributes,
                   LPSECURITY_ATTRIBUTES lpThreadAttributes,                   
                   BOOL bInheritHandles,
                   DWORD dwCreationFlags,
                   LPVOID lpEnvironment,
                   LPCTSTR lpCurrentDirectory,
                   LPSTARTUPINFO lpStartupInfo,
                   LPPROCESS_INFORMATION lpProcessInformation);

参数

  • lpApplicationName:指定新进程要使用的可执行文件的名称
  • lpCommandLine:指定要传给新进程的命令行字符串,lpCommandLine是一个非“常量字符串”的地址。在内部,CreateProcess实际上会修改我们传给它的命令行字符串。但在CreateProcess返回之前,它会将这个字符串还原为原来的样子;鉴于此,若命令行字符包含在文件映像的只读部分,就会引起访问违例。CreateProcess会检查字符串中的第一个标记,并假定此标记是我们想运行的可执行文件的名称
  • lpProcessAttributes:进程内核对象安全属性,若为NULL,将指定默认的安全描述符;若为非NULL,当lpProcessAttributes->bInheritHandle为TRUE时,子进程将继承父进程中所有可继承的句柄;当lpProcessAttributes->bInheritHandle为FALSE时,子进程讲无法继承父进程中的任何句柄
  • lpThreadAttributes:主线程内核对象安全属性,若为NULL,将指定默认的安全描述符;若为非NULL,当lpThreadAttributes->bInheritHandle为TRUE时,父进程的主线程内核对象将被继承;当lpThreadAttributes->bInheritHandle为FALSE时,父进程的主线程内核对象不可继承,不管传给lpProcessAttributes->bInheritHandle的值是多少
  • bInheritHandles:指定子进程是否能继承父进程中可继承的内核对象,若为TRUE则可继承,若为FALSE则不可继承
  • dwCreationFlags:标识了影响新进程创建方式的标志(flag)。多个标志可以使用按位或起来,以便同时指定多个标志组合
    • IDLE_PRIORITY_CLASS:低
    • BELOW_NORMAL_PRIORITY_CLASS:标准
    • ABOVE_NORMAL_PRIORITY_CLASS:高于标准
    • HIGH_PRIORITY_CLASS:高
    • REALTIME_PRIORITY_CLASS:实时
    • DEBUG_PROCESS:父进程希望调试子进程以及子进程将来生成的所有进程
    • DEBUG_ONLY_THIS_PROCESS:只有在关系最近的子进程中发生特定事件时,父进程才会得到通知
    • CREATE_SUSPENDED:创建新进程的同时挂起其主线程。这样一来,父进程就可以修改子进程地址空间中的内存,更改子进程的主线程优先级,或者在进程执行任何代码之前,将此进程添加到一个作业(job)中。父进程修改好子进程之后,可以调用ResumeThread函数来允许子进程执行代码
    • DETACHED_PROCESS:阻止一个基于CUI的进程访问其父进程的控制台窗口,并告诉系统将它的输出发送到一个新的控制台窗口,如果一个基于CUI的进程是由另一个基于CUI的进程创建的,那么默认情况下,新进程将使用父进程的控制台窗口
    • CREATE_NEW_CONSOLE:为新进程创建一个新的控制台窗口。如果同时指定DETACHED_PROCESS和CREATE_NEW_CONSOLE,会导致一个错误
    • CREATE_NO_WINDOWS:不要为应用程序创建人和控制台窗口。可以使用这个标志来执行没有用户界面的控制台应用程序
    • CREATE_NEW_PROCESS_GROUP:修改用户按Ctrl+C或Ctrl+Break时获得通知的进程列表
    • CREATE_DEFAULT_ERROR_MODE:新进程不会进程父进程的错误模式而使用默认的错误模式
    • CREATE_UNICODE_ENVIRONMENT:子进程的环境块应包含Unicode字符。进程的环境块默认包含的是ANSI字符串
    • CREATE_FORCEDOS:强制系统运行一个嵌入在16位OS/2应用程序中的MS-DOS应用程序
    • CREATE_BREAKAWAY_FROM_JOB:标志允许一个作业中的进程生成一个和作业无关的进程
    • EXTENDED_STARTUPINFO_PRESENT:标志向操作系统表明传给lpStartupInfo参数的是一个STARTUPINFOEX结构
    • fdwCreate参数还允许我们指定一个优先级类(priority class),对大多数程序都不应该这样做——系统会为新进程分配一个默认的优先级类,可指定的优先级如下(由低到高):
  • lpEnvironment:指向一块内存,其中包含新进程要使用的环境字符串
  • lpCurrentDirectory:子进程的当前驱动器和目录
  • lpStartupInfo:指向一个STARTUPINFO或STARTUPINFOEX结构,通常情况下是使用默认即可(将所有成员初始化为0,并将cb成员设为此结构的大小)
  • lpProcessInformation:[out],指向一个PROCESS_INFORMATION结构,函数在返回之前,会初始化这个结构体。如前所述,创建一个新的进程,会导致系统创建一个进程内核对象和一个线程内核对象。在创建时,系统会为每个对象指定一个初始的使用计数1.然后,在CreateProcess返回之前,它会使用完全访问权限打开进程对象和线程对象,并将与之相关的句柄放入lpProcessInformation的hProcess和hThread成员中。当CreateProcess在内部打开这些对象时,每个对象的使用计数变为2。这意味着系统要想释放进程对象,进程必须终止(使用计数递减1),而且父进程必须调用CloseHandle(使用计数再次递减1,变为0)。类似地,要想释放线程对象,线程必须终止而且父进程必须关闭到线程对象的句柄

    返回值

  • CreateProcess在进程完全初始化好之前就返回TRUE。这意味着操作系统加载程序(loader)尚未尝试定位所有必要的DLL。如果一个DLL找不到或者不能正确初始化,进程就会终止。因为CreateProcess返回TRUE,所以父进程不会不会注意到任何初始化问题
  • 若失败则返回FALSE

CreateProcess函数

时间: 2024-12-13 03:02:07

CreateProcess函数的相关文章

关于CreateProcess函数一些经验

TCHAR szCmdLine[]={TEXT("E:\\CPL-server\\其他工具\\restartSrv\\bin\\opensavepath.exe")}; TCHAR static szCommandLine[MAX_PATH + 700] = {0}; lstrcpy(szCommandLine, pProgramPath); STARTUPINFO si = {0}; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(ST

windows - 进程 - CreateProcess函数详解

CreateProcess函数原型如下: [cpp] view plaincopy BOOL CreateProcess( PCTSTR pszApplicationName, PTSTR pszCommandLine, PSECURITY_ATTRIBUTES psaProcess, PSECURITY_ATTRIBUTES psaThread, BOOL bInheritHandles, DWORD fdwCreate, PVOID pvEnvironment, PCTSTR pszCurD

CreateProcess函数具体解释

CreateProcess说明:WIN32API函数CreateProcess用来创建一个新的进程和它的主线程,这个新进程执行指定的可执行文件. 函数原型:BOOL CreateProcess(    LPCTSTR lpApplicationName,            LPTSTR lpCommandLine,            LPSECURITY_ATTRIBUTES lpProcessAttributes.    LPSECURITY_ATTRIBUTES lpThreadAt

CreateProcess函数诡异的表现

场景:程序A使用CreateProcess函数去启动另一个程序(.exe)文件,在绝大部分情况下是可以成功启动的,但是在某些电脑上无效. 因为这“某些电脑”实在不好找,终于有一天借到一台这样的电脑. 经过多次实验发现,CreateProcess返回值总为-1,也就是成功创建了进程,而且我是用showPrompt,弹窗打印的该值,如果弹窗,就能创建进程. 最后猜想可能是因为CreateProcess之后,随即程序退出了,并不会等程序B创建完成,会不会太快了,导致电脑没反应过来.最后加了一个Slee

CreateProcess 函数

进程的创建:可以使用CreateProcess 函数 来源:MSDN(竟然不允许MSDN链接 靠 无语) BOOL CreateProcess ( LPCTSTRlpApplicationName, LPTSTRlpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes. LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags,

CreateProcess函数回来的进程ID和任务管理器的不同

1 void Proc() 2 { 3 STARTUPINFO si = { 0 }; 4 PROCESS_INFORMATION pi = { 0 }; 5 CreateProcess("c:/windows/system32/calc.exe", "", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); 6 printf("进程ID=%d,进程句柄%d\n", pi.dwProcessI

[转]vc中调用其他应用程序的方法(函数) winexec,shellexecute ,createprocess

三个SDK函数: WinExec,ShellExecute ,CreateProcess可以实现调用其他程序的要求,其中以WinExec最为简单,ShellExecute比WinExec灵活一些,CreateProcess最为复杂.    WinExec 两个参数,前一个指定路径,后一个指定显示方式.    ShellExecute 可以指定工作目录,并且还可以寻找文件的关联直接打开不用加载与文件关联的应用程序,ShellExecute还可以打开网页,启动相应的邮件关联发送邮件等等.    Cr

[转]WinExec、ShellExecute和CreateProcess及返回值判断方式

[转]WinExec.ShellExecute和CreateProcess及返回值判断方式 http://www.cnblogs.com/ziwuge/archive/2012/03/12/2392472.html 有三个API函数可以运行可执行文件WinExec.ShellExecute和CreateProcess.CreateProcess因为使用复杂,比较少用. WinExec主要运行EXE文件. ⑴ 函数原型: UINT Win Exec(LPCSTR lpCmdLine, UINT u

Delphi 使用CreateProcess创建进程并弹出进程PID值

var  ExeName:PChar;  StartupInfo:TStartupInfo;  ProcessInfo:TProcessInformation;begin  FillChar(ProcessInfo,sizeof(TProcessInformation),0);  FillChar(StartupInfo,Sizeof(TStartupInfo),0);  StartupInfo.cb:=Sizeof(TStartupInfo);  StartupInfo.dwFlags:=ST