管道句柄继承

管道服务器控制是否可以通过以下方式继承其句柄:

  • CreatePipe 函数接收SECURITY_ATTRIBUTES结构。 如果管道服务器将此结构的 bInheritHandle 成员设置为 TRUE,则可以继承 CreatePipe 创建的句柄。
  • 管道服务器可以使用 DuplicateHandle 函数更改管道句柄的继承。 管道服务器可以创建可继承管道句柄的不可继承副本或不可继承管道句柄的可继承副本。
  • CreateProcess 函数使管道服务器能够指定子进程是继承其可继承的所有句柄还是不继承任何句柄。

当子进程继承管道句柄时,系统将允许该进程访问管道。 但是,父进程必须将句柄值传达给子进程。 父进程通常通过将标准输出句柄重定向到子进程来执行此操作,如以下步骤所示:

  1. 调用 GetStdHandle 函数以获取当前标准输出句柄;保存此句柄,以便在创建子进程后还原原始标准输出句柄。
  2. 调用 SetStdHandle 函数,将标准输出句柄设置为管道的写入句柄。 现在,父进程可以创建子进程。
  3. 调用 CloseHandle 函数以关闭管道的写入句柄。 子进程继承写入句柄后,父进程不再需要其副本。
  4. 调用 SetStdHandle 以还原原始标准输出句柄。

子进程使用 GetStdHandle 函数获取其标准输出句柄,该句柄现在是管道写入端的句柄。 然后,子进程使用 WriteFile 函数将其输出发送到管道。 当子项完成管道处理后,它应通过调用 CloseHandle 或通过终止(自动关闭句柄)来关闭管道句柄。

父进程使用 ReadFile 函数从管道接收输入。 数据作为字节流写入匿名管道。 这意味着,从管道读取的父进程无法区分在单独的写入操作中写入的字节,除非父进程和子进程都使用协议来指示写入操作的结束位置。 关闭管道的所有写入句柄时, ReadFile 函数将返回零。 在调用 ReadFile 之前,父进程必须将其句柄关闭到管道的写入端。 如果未完成此操作, ReadFile 操作将无法返回零,因为父进程具有指向管道写入端的打开句柄。

重定向标准输入句柄的过程与重定向标准输出句柄的过程类似,只不过管道的读取句柄用作子级的标准输入句柄。 在这种情况下,父进程必须确保子进程不会继承管道的写入句柄。 如果未完成此操作,则子进程执行的 ReadFile 操作无法返回零,因为子进程具有指向管道写入端的打开句柄。

有关使用匿名管道重定向子进程的标准句柄的示例程序,请参阅 使用重定向的输入和输出创建子进程