我一直在尝试使用Windows API来启动通过匿名管道与父进程通信的子进程。基本思想是使用CreatePipe
在父进程中创建一个或多个管道,然后使用CreateProcess
启动具有继承管道句柄的子进程,STARTUPINFOEX
参数指定PROC_THREAD_ATTRIBUTE_HANDLE_LIST
属性中的继承句柄。
在我看来,从实验上看,句柄列表的第一个元素被用作子进程的标准输入,第二个被用作其标准输出,第三个被用作它的标准错误。我还没有看到任何关于这种行为的文档,我也没想到会这样,因为STARTUPINFO
字段hStdInput
、hStdOutput
、hStdError
(以及dwFlags
中的STARTF_USESTDHANDLES
标志(似乎是专门为传达CreateProcess
调用方关于标准句柄的意图而设计的。在实验上,我觉得PROC_THREAD_ATTRIBUTE_HANDLE_LIST
比STARTF_USESTDHANDLES
更令人惊讶。
所以有两个问题:
- 这种行为是否记录在我遗漏的某个地方
- 如何在继承句柄的同时使用默认行为来确定子进程的标准句柄
UPDATE:事实证明,我看到的行为是特定于我作为子进程启动的应用程序的。它一定一直在检查继承的句柄,并对它们执行特定于顺序的操作。大多数Windows应用程序的行为都不是这样的。
PROC_THREAD_ATTRIBUTE_HANDLE_LIST
扩展属性用于明确指定特定进程继承的处理程序。
陈的博客提供了更多细节,
但所有这些可继承性的篡改仍然有一个致命的缺陷:如果同一进程中的两个线程都调用Createprocess,但是不同意他们希望继承哪些句柄?例如假设您有一个函数CreateProcessWithSharedMemory它的工作是启动一个进程,向它传递一个定制的共享内存块假设两个线程同时运行此函数。
Windows Vista允许您通过您希望bInherithandles参数指向的句柄的显式列表应用于。(如果传递显式列表,则必须为bInherit手柄。(和以前一样,对于要继承的句柄也必须标记为可继承。
博客给出了详细的代码示例和实现方法。
有关父子进程之间的匿名通信,请参阅:
- 创建具有重定向输入和输出的子进程
PROC_THREAD_ATTRIBUTE_HANDLE_LIST
覆盖STARTF_USESTDHANDLES
,不会有任何效果。相反,子进程将不会继承父进程的句柄。