使用Windows API在C中创建子进程时,可以允许从父对象继承句柄 . 在Microsoft示例"Creating a Child Process with Redirected Input and Output"中,将子进程'std in / out重定向到父进程创建的管道,必须允许继承以使重定向管道可用 .
我试图 Build 一个超时功能,它只会在给孩子调用 TerminateProcess()
并继续生命之前阻止一段时间 .
但是,我发现通过允许句柄继承,子进程还有一个句柄(可用Process Explorer可见)到输出文件 . 我不希望子进程获取此句柄,但在这种情况下(此演示类)的父级也不知道句柄,因此我目前无法使用 SetHandleInformation()
来专门取消标记输出文件以将其从继承中排除 .
我确信必须有一个更好的方法来继承我想要的特定句柄,而不允许"blanket"继承通过非预期和不需要的句柄 . 不幸的是,我一直无法找到解决方案,浏览了尽可能多的相关MSDN文章,并且将Google自己置于沮丧状态 .
至少,我需要做一些事情来移除子句中的句柄,而不必在演示类中使用这些句柄(它们由调用类使用,并且此演示类没有明确知道它们的存在) .
任何更具选择性继承的解决方案?我特别感兴趣的是允许我明确声明要继承的句柄的解决方案,如果存在这样的解决方案,则不会继承所有未指定的句柄 .
非常感谢你 .
2 回答
如果输出文件句柄由子进程继承,那么这是因为父进程中的代码打开文件明确声明文件句柄应该是可继承的 . 它传递了CreateFile的
lpSecurityAttributes
参数的值 . 默认状态是句柄不可继承 .在我看来,你的流程创建类不应该试图猜测已经打开文件的调用者 .
但是,如果您对确切处理新进程所需的内容有特殊了解,那么从Windows Vista开始,就有一种机制可以指定应该继承哪些句柄 . 当您准备调用
CreateProcess
时,请使用STARTUPINFOEX
结构而不是通常的STARTUPINFO
. 它有一个lpAttributeList
成员 . 分配并初始化它,然后使用UpdateProcThreadAttribute和PROC_THREAD_ATTRIBUTE_HANDLE_LIST
来设置要继承的句柄列表 . 所有句柄都需要是可继承的,并且在调用CreateProcess
时仍需要指定bInheritHandles = true
. 您还需要在dwCreationFlags
参数中包含EXTENDED_STARTUPINFO_PRESENT
. Raymond Chen demonstrated the technique in an article in 2011.如果添加的功能不是't available to you, then you could certainly try to [enumerate all your program' s打开句柄]并使用SetHandleInformation设置它们的所有继承属性,但这似乎超出了其作业是创建子进程的函数的范围 . 让创建句柄的代码担心它们是否应该是可继承的 .
您可以使用SetHandleInformation清除输出句柄上的
HANDLE_FLAG_INHERIT
位,这将阻止子进程继承它 .