CreateProcess 函数原型:

BOOL CreateProcess(PCTSTR   pszApplicationName,PTSTR    pszCommandLine,PSECURITY_ATTRIBUTES psaProcess,PSECURITY_ATTRIBUTES psaThread,BOOL  bInheritHandles,DWORD   fdwCreate,PVOID pvEnvironment,PCTSTR    pszCurDir,PSTARTINFO    psiStartInfo,PROCESS_INFORMATION    ppiProcInfo);

当一个线程调用 CreateProcess 函数时,系统会创建一个进程内核对象,并将这个内核对象的使用计数初始化为 1,系统然后为这个新进程创建一个虚拟地址空间并将可执行文件的代码和数据还有所有需要的 DLL 加载到这个地址空间中,接着,系统为新进程的主线程创建了一个线程内核对象,这个线程开始执行由链接器设置的 C/C++ 运行时启动代码,最后才是你提供的 main 函数开始执行。如果系统成功地创建了新进程和主线程,CreateProcess 返回 TRUE。注意:CreateProcess 函数在进程被完成初始化完成之前返回,这意味着,如果一个所需的 DLL 没有找到或没有正确初始化,进程会终止,但父进程不会知道任何有关初始化的问题。

pszApplicationName 和 pszCommandLine 参数

pszCommandLine 是一个指向 TCHAR 类型的指针,CreateProcess 函数期望你传递一个非常量字符串,这个函数内部会对这个参数进行修改,如果将这个参数设置为常量字符串,会发生访问冲突错误。

pszCommandLine 参数指定了 CreateProcess 函数用来创建新进程的一个完整的命令行,如果 CreateProcess 函数接收到一个 pszCommandLine 参数,函数会假设这个字符串表示一个可执行文件,并假设这个文件有一个 .exe 后缀,CreateProcess 函数会以下面的顺序来搜索这个可执行文件:

1. 包含调用进程可执行文件的目录

2. 调用进程的当前目录

3. Windows\System32 目录,这个目录可通过 GetSystemDircetory 获得

4. Windows 目录

5. 列在 PATH 环境变量中的目录

如果给定的文件名包含了全路径名,系统会只在指定路径中查找可执行文件而不会再搜索以上的目录。

大多数情况下 pszApplicationName 这个参数设置为 NULL,可是如果设置了这个参数,系统会执行这个参数表示的可执行文件,系统不会假设这个参数指定的文件具有 .exe 后缀,所以你必须提供一个完整的名称,系统也不会在以上指定的目录中查找相应的可执行文件,它只会搜索当前目录,如果当前目录中没有可执行文件,CreateProcess 会失败。CreateProcess 有这个参数的原因是为了支持 POSIX 子系统。

psaProcess、psaThread 和 bInheritHandles 参数

psaProcess 和 psaThread 参数表示创建的进程对象和线程对象期望的安全设置,可以将这两个参数都设置为 NULL,系统会给这些对象设置默认的安全描述符。用户还可通过设置这两个参数的 SECURITY_ATTRIBUTES 结构的 bInheritHandle 成员为 TRUE,父进程之后创建的子进程可以继承这些进程和线程的句柄。例如,进程 A 创建了进程 B,将 psaProcess 参数的 SECURITY_ATTRIBUTES 结构的 bInheritHandle 成员设置为 TRUE,将 psaThread 参数的 SECURITY_ATTRIBUTES 结构的 bInheritHandle 成员设置为 FALSE,CreateProcess 返回后,ppiProcInfo 参数结构分别返回了进程 B 的进程和线程句柄,这两个句柄在进程 A 的句柄表中返回的进程句柄标志为可继承,而线程句柄会被打上不可继承标志。之后的某个时刻,进程 A 又创建了进程 C,并向 CreateProcess 函数传递了一个值为 TRUE 的 bInheritHandle 参数,进程 C 创建成功后,进程 A 中的所有可继承句柄都会复制到进程 C 的句柄表中,这样,进程 B 的句柄在进程 C 中可以正确地访问到,而 B 进程的线程句柄不会被进程 C 看到。

bInheritHandle 参数,如上所述,这个参数设置为 TRUE 表示可将父进程的句柄表中可继承句柄继承到新创建的子进程中去。继承的句柄与父进程有相同的句柄值和相同的访问权限。

fdwCreate 参数

这个参数标志指出新进程怎样被创建,还允许你指定一个优先级类型。

pvEnvironment 参数

这个参数是一个向新进程传递的环境变量块字符串的地址,父进程可以使用 GetEnvironmentStrings 函数来取得这个地址并传递给 CreateProcess 函数,大多数情况下传递一个 NULL 给这个函数,这样函数也会在内部调用 GetEnvironmentStrings 函数以便将父进程的环境变量块继承给子进程。

pszCurDir 参数

这个参数允许父进程设置子进程的当前驱动器和当前目录,如果这个参数为 NULL,新进程的当前驱动器和当前目录与父进程的相同,如果这个参数不为 NULL,必须在路径中指定一个驱动器号。

psiStartInfo 参数

当前创建一个新的进程时,由 Windows 使用这个参数的数据结构的成员。大多数应用程序都希望使用这个参数的默认值创建新的进程,所以一般只是简单地将这个数据结构的所有成员置 0,如下所示:

STARTUPINFO si = { sizeof(STARTUPINFO) };

如果你没有将这个结构的成员置 0,它的成员会包含一些垃圾数据,那么 CreateProcess 可能会失败或者新进程会有一些不可预料的行为。

ppiProcInfo 参数

这是一个指向 PROCESS_INFOMATION 结构的指针,你必须为这个结构分配空间,CreateProcess 会在返回之前初始化这个结构。

在子进程运行之前,系统创建了一个子进程的内核对象和子进程主线程的内核对象,并将这两个对象的初始计数设置为 1,CreateProcess 返回之前,会创建与父进程相关的两个句柄并分别初始化 PROCESS_INFORMATION 结构的 hProcess 和 pThread 两个成员,这样,子进程内核对象和子进程主线程内核对象的使用计数又分别增加了 1。如果父进程不使用这个两个句柄,应该在函数返回之后立即关闭这两个句柄,以免造成资源泄漏。

当前一个进程的内核对象被创建后,系统会赋于这个内核对象一个唯一的标识符,同样,也会有一个主线程对象的唯一标识符。这个标识符系统保证它的唯一性,但是,当一个内核对象被释放后,这个标识符可能会被立即用于另一个内核对象。如果你想要使用这个标识符完成一些操作,必须记住不能将这个标识符对应的内核对象释放,所以当这个标识符使用完成后才调用 CloseHandle 才是最安全的方法。使用 GetCurrentProcessId 来获取当前进程的标识符,使用 GetProcessId 来获取指定内核对象句柄的标识符,使用 GetProcessIdOfThread 来获取线程所在进程的标识符。

转载于:https://www.cnblogs.com/Fly-pig/archive/2011/01/18/1938357.html

Windows via C/C++ 学习(8)CreateProcess 函数相关推荐

  1. Windows 进程之四 CreateProcess函数

    Windows 进程之四 CreateProcess函数 一.CreateProcess 函数 1.1.pszImageName 和pszCmdLine 参数 一.CreateProcess 函数 这 ...

  2. windows CreateProcess函数详解

    TStartupInfo  结构体详解 typedef struct _STARTUPINFO { DWORD cb; //包含STARTUPINFO结构中的字节数.如果Microsoft将来扩展该结 ...

  3. 分享Silverlight/WPF/Windows Phone一周学习导读(10月30日-11月6日)

    分享Silverlight/WPF/Windows Phone一周学习导读(10月30日-11月6日) 本周Silverlight学习资源更新 Silverlight 定位 niejunhua [学习 ...

  4. 分享Silverlight/WPF/Windows Phone一周学习导读(8月15日-8月19日)

    分享Silverlight/WPF/Windows Phone一周学习导读(8月15日-8月19日) 本周Silverlight学习资源更新: Silverlight Tools 4安装时的错误提示 ...

  5. Windows进程与线程学习笔记(九)—— 线程优先级/进程挂靠/跨进程读写

    Windows进程与线程学习笔记(九)-- 线程优先级/进程挂靠/跨进程读写 要点回顾 线程优先级 调度链表 分析 KiFindReadyThread 分析 KiSwapThread 总结 进程挂靠 ...

  6. Windows进程与线程学习笔记(八)—— 线程切换与TSS/FS

    Windows进程与线程学习笔记(八)-- 线程切换与TSS/FS 要点回顾 线程切换与TSS 内核堆栈 调用API进0环 实验:分析SwapContext 线程切换与FS 段描述符结构 分析Swap ...

  7. Windows进程与线程学习笔记(七)—— 时间片管理

    Windows进程与线程学习笔记(七)-- 时间片管理 要点回顾 基本概念 CPU时间片 分析 KeUpdateRunTime 分析 KiDispatchInterrupt 备用线程 总结 要点回顾 ...

  8. Windows进程与线程学习笔记(六)—— 线程切换

    Windows进程与线程学习笔记(六)-- 线程切换 主动切换 分析KiSwapContext 分析SwapContext 分析KiSWapThread 总结 时钟中断切换 系统时钟 分析INT 0x ...

  9. Windows进程与线程学习笔记(五)—— 模拟线程切换

    Windows进程与线程学习笔记(五)-- 模拟线程切换 ThreadSwitch代码分析 ThreadSwitch.cpp ThreadCore.h ThreadCore.cpp 总结 Thread ...

最新文章

  1. Transformer的潜在竞争对手QRNN论文解读,训练更快的RNN
  2. Servlet中转发和重定向的路径问题以及表单提交路径问题
  3. getRotationMatrix2D函数
  4. JACK——PaintRobot Exercise9
  5. oracle里的ols机制,Oracle ASM的AU(Allocation units)分配
  6. cpu倍频模式怎么调_CPU频率被锁定到800mhz怎么办?
  7. configurablebeanfactory
  8. 重载(Overload)和重写(Overide)
  9. mysql一对多关联查询分页_mysql一对多关联查询分页错误问题的解决方法
  10. iphone通知和android,手机App 通知数量太多,让你备感压力吗?教你如何消除令人心烦的信息通知(iPhone、Android)...
  11. python定义一个circle类、根据圆的半径_定义一个“圆”类Circle,该圆类的数据成员包括:圆心点位置及圆的半径...
  12. 计算机毕业设计中用Java+Html+MySQL 实现注册、登录(servlet框架)-(二
  13. 计算机电源怎么设置玩游戏不卡,BIOS怎么找到显卡的设置
  14. 计算机维护费可以跨年吗,税控技术维护费是否可以跨年抵扣?
  15. 鲁班学艺 ---学三个月的,手艺扎根在眼里;学三年的,手艺扎根在心里
  16. wireshark分析无线wifi包
  17. python后端需要什么基础_学习Python需要哪些基础知识?_后端开发
  18. Fly-小学妹都喜欢的Go后端项目
  19. 为自己的站点实现访客统计
  20. spring boot 中阿里druid 数据源配置及密码加密

热门文章

  1. vsftp客户端_vsftp 如何登陆?
  2. oracle和mysql文件怎么打开_mysql与oracle数据库停止与打开的批处理文件
  3. STM8单片机 ADC模拟看门狗中文资料错误
  4. JavaScript基础(ECMAScript)
  5. ZZ_MODIFIED_GEEBINF 不可用
  6. 吴恩达深度学习2.1练习_Improving Deep Neural Networks(Initialization_Regularization_Gradientchecking)
  7. 高仿富途牛牛-组件化(五)-如何去管理炒鸡多的小窗口
  8. Studio 3T:MongoDB SQL探究
  9. sql order by 结合case when then
  10. Spring中,修改注入的bean名称