在Windows中,一个人如何可以创建一个子进程,并捕获它的标准输入,标准输出,和标准错误,而无需复制任何可继承的句柄? [英] In Windows, how can one create a child process and capture its stdin, stdout, and stderr, without duplicating any inheritable handles?

查看:315
本文介绍了在Windows中,一个人如何可以创建一个子进程,并捕获它的标准输入,标准输出,和标准错误,而无需复制任何可继承的句柄?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有至少三个部分来这个问题,所以多多包涵:

There are at least three parts to this problem, so bear with me:

1)的CreateProcess有一个参数bInheritHandles,导致子进程继承所有可继承句柄的父进程。此选项必须设置为TRUE,允许家长来指定标准输入,标准输出,和标准错误处理在STARTUPINFO参数孩子。

1) CreateProcess has a parameter bInheritHandles, that causes the child process to inherit all of the inheritable handles in the parent process. This option must be set to TRUE to allow the parent to specify stdin, stdout, and stderr handles for the child in the STARTUPINFO parameter.

2)在Win32中删除和重命名文件时有一个以上的手柄开到同一个文件可能会失败。

2) In Win32 deleting and renaming files can fail when there is more than one handle open to the same file.

3)微软CRT的open()函数将默认创建可继承的句柄。此外默认创建的文件句柄,从上面的问题2遭殃。

3) The Microsoft CRT's open() function will by default create inheritable handles. Additionally the file handles created by default suffer from problem 2 above.

这个神奇的组合创建以下操作问题:库调用open()和不希望以后的重命名和删除失败。其他地方在此过程中的另一个库B被调用设置为TRUE(捕捉标准输入/输出/错误)暂时创建重复把手bInheritHandles CreateProcess的。现在偶尔库中的文件操作失败。自然地库A和B是由不同的人维护。我也知道,使用open()和从类似问题的困扰另一个库A'的。

This magic combination creates the following operational problem: Library A calls open() and doesn't expect subsequent renames and deletes to fail. Elsewhere in the process another library B is calling CreateProcess with bInheritHandles set to TRUE (to capture stdin/out/err) temporarily creating duplicate handles. Now occasionally library A's file operations fail. Naturally library A and B are maintained by separate people. I also know of another library A' that uses open() and suffers from a similar problem.

知识库文章讨论相关的问题和解决方案。然而,它仍依赖于调用与父进程设置为TRUE bInheritHandles CreateProcess的,因此它并没有解决这一问题。

This kb article discusses a related problem and solution. However it still relies on calling CreateProcess with bInheritHandles set to TRUE in the parent process, so it doesn't solve this problem.

我,如果没有一个很好已知的解决方案?

I am wondering if others have hit this problem and if there isn't a well known solution?

以上基本的知识库文章暗示,调用设置为TRUE bInheritHandles CreateProcess的是活泼的,所以我的倾向是固定库B使得它永远不会做到这一点。我想通过这样做:

The kb article above essentially implies that calling CreateProcess with bInheritHandles set to TRUE is racy, so my inclination is to fix library B such that it never does that. I would do this by:


  1. 创建一个暂停中间过程(最好用RUNDLL运行库B中的自定义入口点)设置为false bInheritHandles。

  2. 创建标准输入/输出/ ERR管道和DUP这些中间过程的正确目的。

  3. 通过欺骗手柄中间过程弄好了。

  4. 简历的中间过程。

  5. 从中间过程中填写的STARTUPINFO从父管道和调用CreateProcess的设置为TRUE bInheritHandles。

这是一个很好的策略,或者是有一些更好的解决方案?
你会如何​​建议传递欺骗手柄中间过程在第3步?
是RUNDLL +自定义的切入点一种可靠的方式来设置中间过程步骤1?

Is this a good strategy or is there some better solution? How would you recommend passing the duped handles to the intermediate process in step 3? Is rundll + custom entry point a reliable way to setup the intermediate process in step 1?

推荐答案

您可以使用 PROC_THREAD_ATTRIBUTE_HANDLE_LIST 扩展属性明确指定到底哪个处理特定进程继承。

You can use the PROC_THREAD_ATTRIBUTE_HANDLE_LIST extended attribute to explicitly specify exactly which handles a particular process inherits.

Raymond Chen的博客文章编程控制哪些句柄在新的Win32进程继承包括样品code这样做的。

Raymond Chen's blog post "Programmatically controlling which handles are inherited by new processes in Win32" includes sample code for doing this.

短的版本:


  • InitializeProcThreadAttributeList()来创建一个属性列表

  • InitializeProcThreadAttributeList() to create an attribute list

UpdateProcThreadAttribute指定手柄继承

UpdateProcThreadAttribute to specify the handles to inherit

lpAttributeList 在STARTUPINFOEX成员集中

lpAttributeList member set in STARTUPINFOEX

EXTENDED_STARTUPINFO_ preSENT标志集

EXTENDED_STARTUPINFO_PRESENT flag set in call to CreateProcess

需要Windows Vista中,所以可能没有解决,当最初被问到这个问题的OP的问题,但每个人都在使用Vista或更高版本到现在,对不对? : - )

Requires Windows Vista, so might not have solved the OPs problem when this question was originally asked, but everyone's using Vista or later by now, right? :-)

这篇关于在Windows中,一个人如何可以创建一个子进程,并捕获它的标准输入,标准输出,和标准错误,而无需复制任何可继承的句柄?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆