代码之家  ›  专栏  ›  技术社区  ›  Vasilly.Prokopyev

仅重定向子进程stdin,并从stdout和stderr中删除数据

  •  0
  • Vasilly.Prokopyev  · 技术社区  · 10 年前

    我可以使用 STARTF_USESTDHANDLES 标志在 STARTUPINFO 要重定向的结构 stdin , stdout , stderr 进程的,由创建 CreateProcess .

    Documentation 对这个案子说( 启动_使用标准句柄 标志存在):

    hStdInput、hStdOutput和hStdError成员包含其他 信息如果在调用其中一个进程时指定了此标志 创建函数时,句柄必须是可继承的 bInheritHandles参数必须设置为TRUE。关于更多信息, 请参见句柄继承。

    但对于这些成员本身(hStdInput等),相同的文档表示(例如-hStdError):

    如果dwFlags指定STARTF_USEDHANDLES,则此成员是标准 进程的错误句柄。否则,将忽略此成员,并且 标准错误的默认值是控制台窗口的缓冲区。

    如果我将管道连接到子进程stdout和 不要 从中读取数据,其缓冲区将溢出,根据 this doc ,子进程将在尝试在stdout上写入数据时挂起一段时间,因为

    如果在写入所有字节之前管道缓冲区已满,则WriteFile 直到另一个进程或线程使用ReadFile 更多可用缓冲空间。

    我能安全通过吗 无效的 对于 hStdOutput hStdError 的成员 启动信息 结构时 启动_使用标准句柄 国旗是为了避免这种情况?或者我必须让轮询线程清除管道中的数据,以防止缓冲区溢出?

    我想要可靠的解决方案,所以请您发布任何参考文档,说明这是从标准输出中删除数据的合法方法。

    1 回复  |  直到 10 年前
        1
  •  2
  •   Ross Ridge    10 年前

    打开 NUL 设备,并将其用作 hStdOutput hStrError 手柄。写入NUL设备的任何数据都将被忽略而不会导致错误。这比没有句柄更好,因为对标准输出的写入失败或子进程中的标准错误可能会导致其过早退出。确保按照文档中提到的那样,使句柄可继承。

    类似于:

    SECURITY_ATTRIBUTES secattr;
    secattr.nLength = sizeof secattr;
    secattr.lpSecurityDescriptor = NULL;
    secattr.bInheritHandle = TRUE;
    hnul = CreateFile("NUL", GENERIC_WRITE, 0, &secattr, OPEN_EXISTING, 0, NULL);
    startupinfo.hStdOutput = hnul;
    startupinfo.hStdError = hnul;
    

    我不确定 核反应堆 该设备由Microsoft在任何地方正式记录。然而,在Windows出现之前,它就一直是Windows的一部分。MS-DOS 1.0支持它 /dev/null ,如果你熟悉的话。