如何在 Windows 上的 CreateProcess() 中不继承标准输入、标准输出和标准错误
Posted
技术标签:
【中文标题】如何在 Windows 上的 CreateProcess() 中不继承标准输入、标准输出和标准错误【英文标题】:How to NOT inherit stdin, stdout and stderr in CreateProcess() on Windows 【发布时间】:2021-12-30 15:06:42 【问题描述】:CreateProcessW()
,接受标志bInheritHandles
。如果设置为FALSE
,则只继承stdin
、stdout
和stderr
,其他不继承。
继承所有内容有时很烦人,因此可以使用extended startup info 显式配置要继承的句柄。在这种情况下,stdin
、stdout
和 stderr
默认情况下不继承,但可以通过将它们包含在 UpdateProcThreadAttribute()
的继承句柄中来继承它们。
这样,例如可以只继承stderr
。
但作为一个具体情况,如何禁用它们(包括stdin
、stdout
和stderr
)?如果我们为属性PROC_THREAD_ATTRIBUTE_HANDLE_LIST
传递NULL
/空列表,UpdateProcThreadAttribute()
将失败。
请注意,在这种情况下,我不想重定向 stdin
、stdout
和 stderr
(我不想写入/读取它们),我只想禁用它们。
作为一种解决方法,可以创建一个虚拟的HANDLE
并继承它,这样stdin
、stdout
和stderr
就可以被禁用,但这有点笨拙。 bInheritHandles
设置为 FALSE
不起作用,因为它启用了 stdin
、stdout
和 stderr
。传递 DETACHED_PROCESS
可能会产生其他副作用 (?)。
实现这一目标的正确方法是什么?
【问题讨论】:
"在这种情况下,我不想重定向stdin
、stdout
和stderr
(我不想写入/读取它们),我只是想要禁用它们” - 这听起来像是XY Problem 对我来说。为什么要禁用它们?您要解决的根本问题是什么?
我开发了一个执行一些命令的程序。有时,我想在我的程序控制台中输出和/或这些命令,有时我想捕获它们(所以我使用管道),有时我只想静默执行命令。
"有时我只想默默地执行命令" - 你试过在CreateProcess()
上使用CREATE_NO_WINDOW
或DETACH_PROCESS
标志吗?见What is the difference between DETACH_PROCESS and CREATE_NO_WINDOW process creation flags for createProcess function
是的,我测试了DETACH_PROCESS
,它似乎有效,但正如问题中提到的,我担心可能会出现意想不到的副作用。
如果设置为FALSE,则只继承stdin、stdout和stderr,其他不继承。 - 不。在这种情况下没有继承任何东西
【参考方案1】:
哦,如果设置了STARTF_USESTDHANDLES
,如果bInheritHandles
设置为FALSE
,那么根本就没有句柄被继承,这正是我想要的:
STARTUPINFOW si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
// This is important to disable stdin, stdout and stderr
si.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
// si.hStdInput, si.hStdOutput and si.hStdError must not be set
编辑:或者,如上所述,here 在dwCreationFlags
(CreateProcess()
的参数)中传递DETACHED_PROCESS
也可以。
【讨论】:
以上是关于如何在 Windows 上的 CreateProcess() 中不继承标准输入、标准输出和标准错误的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Windows 上的 Cygwin 中运行 crontab?
如何检查程序是不是在 Windows 上的 Ubuntu 上的 Bash 中运行,而不仅仅是普通的 Ubuntu?
如何在 Windows 上的 python 中启动一个进程?
如何在 Windows 上的 Python 3 中连接到 MySQL?