CreateProcess()函数详细解释

CreateProcess函数用于创建进程,涉及参数如pszApplicationName、pszCommandLine、安全属性、句柄继承等。该函数会查找可执行文件,创建进程内核对象和线程对象,处理命令行参数,并允许控制句柄继承。pszCommandLine应避免指向只读内存,否则可能导致Access Violation。安全属性通过SECURITY_ATTRIBUTES结构指定,bInheritHandles控制句柄继承。函数返回后,需要使用PROCESS_INFORMATION结构处理进程信息并关闭句柄。
摘要由CSDN通过智能技术生成

函数原型  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

  );

CreateProcess函数

  CreateProcess函数用于创建进程:

  1. BOOL CreateProcess(
  2. PCTSTR pszApplicationName,
  3. PTSTR pszCommandLine,
  4. PSECURITY_ATTRIBUTES psaProcess,
  5. PSECURITY_ATTRIBUTES psaThread,
  6. BOOL bInheritHandles,
  7. DWORD fdwCreate,
  8. PVOID pvEnvironment,
  9. PCTSTR pszCurDir,
  10. PSTARTUPINFO psiStartInfo,
  11. PPROCESS_INFORMATION ppiProcInfo);

线程调用CreateProcess时,系统会创建一个进程内核对象,将其引用计数初始化为1(进程内核对象并不是进程本身,它只是操作系统用来管理进程的数据结构,其中包含了进程的一些统计信息)。然后系统为新进程开辟虚拟地址空间,并将可执行文件的代码和数据以及所需的DLL装载到该地址空间中。接着系统为进程主线程创建线程内核对象,并将其引用计数初始为1(同进程一样,线程内核对象也不是线程本身,而且操作系统用来管理线程的数据结构)。主线程将链接器设置的入口点函数作为C/C++运行时启动函数调用,这些启动函数最终又调用代码中的入口点函数如WinMain、wWinMain、main和 wmain。当操作系统成功创建了新的进程和主线程后,CreateProcess返回TRUE。以上是CreateProcess的简要介绍,下面我们来详细讨论它的参数。

pszApplicationName和pszCommandLine
  pszApplicationName和pszCommandLine分别表示进程使用的可执行文件名和向其传递的命令行字符串,我们先来看看 pszCommandLine参数。注意pszCommandLine是PTSTR,这意味着你必须为其传递指向非常量字符串的地址。 CreateProcess内部会更改向其传递的命令行字符串,但在CreateProcess返回之前,它会将该字符串恢复原样。这一点是非常重要的,因为如果你向CreateProcess传递的命令行字符串位于进程的只读存储区,就会发生Access Violation错误。比如,下面的代码执行时会触发Access Violation,因为微软的C/C++编译器会把常量字符串放入只读存储区(注意早期的微软C/C++编译器会将常量字符串放在可读写存储区,因此下面的代码在旧的编译环境下不会出错):

  1. STARTUPINFO si = { sizeof(si) };
  2. PROCESS_INFORMATION pi;
  3. CreateProcess(NULL, TEXT("NOTEPAD"), NULL, NULL,
  4. FALSE, 0, NULL, NULL, &si, &pi);

解决这个问题的方法很简单,将命令行字符串复制到临时缓冲区既可,如下所示:

  1. STARTUPINFO si = { sizeof(si) };
  2. PROCESS_INFORMATION pi;
  3. TCHAR szCommandLine[] = TEXT("NOTEPAD");
  4. CreateProcess(NULL, szCommandLine, NULL, NULL,
  5. FALSE, 0, NULL, NULL, &si, &pi);

微软在其C++编译器选项中提供了/GF开关,/GF打开时,程序中所有用到的常量字符串将只维护单一副本,且位于只读存储部分。在调用 CreateProcess时,开发人员应该打开/GF开关并使用缓冲区。我们希望微软在未来版本的Windows中会改进CreateProcess,使其接受常量字符串作为命令行参数,并在其内部分配/释放临时缓冲区而不是让API调用者来做。另外,假如你使用常量ANSI字符串作为 CreateProcess参数,并不会发生Access Violation错误,我们在前面的章节已经提到过,许多WinAPI函数的ANSI版本会将ANSI参数转换为UNIDOE编码后调用其 Unicode版本,CreateProcess会把ANSI字符串转换为Unicode编码后放在临时缓冲区,并调用Unicode版的 CreateProcess,因此不会触发Access Violation。
  pszCommandLine参数指定了 CreateProcess创建新进程所需的完整命令行。当CreateProcess解析该参数时,它会检查命令行参数中的第一个标记,并将其作为进程要执行的可执行文件名,如果该文件名没有指定后缀,函数将把它当作exe文件。CreateProcess会按下面的顺序查找该文件:
1. 包含当前进程可执行文件的目录
2. 当前进程的当前目录
3. Windows系统目录,既GetSystemDirectory返回的目录
4. Windows目录
5. PATH环境变量列出的目录
当然,如果文件名包含了完整路径,系统将会在该路径中查找文件而不会再做上面的搜索。如果系统找到了可执行文件,它会创建一个新的进程并把可执行文件的代码和数据映射到进程的地址空间,然后调用CRT启动函数(linker选项卡中的入口点函数),接着CRT启动函数检查命令行参数,过滤掉其中的可执行文件部分,并把剩下字符串的地址作为pszCmdLine传给wWinMain/WinMain。

以上情形都是在pszApplicationName为NULL时发生的。 pszApplicationName指定了进程要执行的可执行文件的名称,假如没有指定文件后缀,系统并不会做任何处理。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CreateProcess函数是一个Windows API函数,用于创建一个新的进程。它的功能是根据指定的可执行文件名、命令行参数、进程安全属性等参数,创建一个新的进程,并返回新进程的句柄和标识符。 使用CreateProcess函数可以很方便地创建新的进程,实现并行执行多个任务的功能。它通常在编写Windows应用程序时使用,可以创建包括GUI和控制台程序在内的各种类型的进程。 使用CreateProcess函数需要提供一些必要的参数,包括可执行文件名和命令行参数,这些参数可以指定新进程要执行的具体任务。还可以指定一些可选的参数,如进程安全属性、标准输入输出的重定向等。通过这些参数的设置,可以灵活地控制新进程的行为。 CreateProcess函数创建新进程后,会返回一个句柄和标识符,可以用于其他操作,如监视进程状态、与新进程进行通信等。可以通过这些句柄和标识符来控制和管理新进程,实现进程间的交互和同步。 在使用CreateProcess函数时,需要注意一些问题,如确保传递给它的参数正确有效,保证新进程的可靠运行,防止资源泄漏等。同时,需要对新进程进行适当的管理和关闭,以避免产生僵尸进程或资源浪费问题。 总之,CreateProcess函数是一个重要的Windows API函数,能够创建新的进程,并提供了丰富的参数和功能,能够满足不同需求下的进程创建和管理。通过它的使用,可以实现进程间的并行执行和相互通信,提高应用程序的性能和灵活性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值