设为首页 收藏本站
查看: 1062|回复: 0

Windows via C/C++ 学习(8)CreateProcess 函数

[复制链接]

尚未签到

发表于 2015-5-23 14:47:27 | 显示全部楼层 |阅读模式
  CreateProcess 函数原型:
BOOL CreateProcess(
PCTSTRpszApplicationName,
PTSTRpszCommandLine,
PSECURITY_ATTRIBUTESpsaProcess,
PSECURITY_ATTRIBUTESpsaThread,
BOOLbInheritHandles,
DWORDfdwCreate,
PVOIDpvEnvironment,
PCTSTRpszCurDir,
PSTARTINFOpsiStartInfo,
PROCESS_INFORMATIONppiProcInfo);
  当一个线程调用 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 来获取线程所在进程的标识符。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-69909-1-1.html 上篇帖子: Windows Phone 8 显示当前项目的使用内存,最大峰值,最大内存上限 下篇帖子: 快速构建Windows 8风格应用18-基础控件I
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表