【问题标题】:Read another process' stdout in C++在 C++ 中读取另一个进程的标准输出
【发布时间】:2010-11-04 01:53:27
【问题描述】:

在 Windows 中,有没有办法在 C++ 中启动一个进程,然后在完成后将它吐出的内容读取到标准输出中?如有必要,必须使用提升的权限(在 Vista 或更高版本上)运行该进程。

我目前正在使用 ShellExecuteEx() 来启动进程并运行 while 循环,直到 GetExitCodeProcess() 不再通过 lpExitCode 参数返回 STILL_ACTIVE(在每次迭代期间调用 WaitForSingleObject() 会等待 100 毫秒)。

【问题讨论】:

  • 你可以在启动进程时将标准输出重定向到命名管道吗? (不是 C++ 开发人员,因此发表评论)
  • 问题在于,要运行提升的进程,您必须使用 ShellExecuteEx()runas 动词。而ShellExecuteEx() 不支持输出重定向 AFAICT。

标签: c++ windows stdout


【解决方案1】:

没有简单的方法可以做到这一点。

使用 runas 动词调用 ShellExecuteEx() 会向 AppInfo NT 服务 发送 RPC 消息,然后从提升的会话中运行应用程序。没有 API 可以轻松地将提升的进程的输入/输出连接到您的应用程序。

Thomas Hruska 在他的 The Code Project article 中介绍了解决此问题的 CreateProcessElevated() 函数的实现。

CreateProcessElevated() 不是直接运行提升的程序,而是依赖另一个可执行文件,它接收 stdin,stdout,stderr 命名管道的名称,并在调用 CreateProcess() 之前在提升的会话中重新创建它们的句柄.

【讨论】:

  • 我喜欢 Code Project 解决方案。不幸的是,由于它涉及一个单独的 DLL,我将无法将它用于我的特定项目,这是一个安装程序的引导应用程序。 (叹气!我猜是回到绘图板。)
【解决方案2】:

您应该将您对 ShellExecuteEx 的使用替换为 CreateProcesslpStartupInfo 参数允许进程的标准输入和标准输出句柄。只需使用您作为参数传递的CreatePipe 创建一个匿名管道。这个MSDN article 有一个如何做到这一点的例子。

【讨论】:

  • 但 CreateProcess() 不能用于启动提升的进程,除非父进程也被提升。
【解决方案3】:

您需要为子进程创建一个命名管道。 This MSDN article 解释并有代码示例。

你应该能够从中得到它。

【讨论】:

  • 不幸的是,这个解决方案使用 CreateProcess() 而不是 ShellExecuteEx()。
【解决方案4】:

你不能使用 CreateProcess/ShellExecuteEx 来执行一个带有 stdout/stderr 重定向的 cmd shell,进而调用你的进程吗?

“cmd /c YourProcess.exe {参数}”等?

【讨论】:

    猜你喜欢
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2010-11-08
    • 2011-09-18
    • 2011-11-09
    • 2011-03-25
    • 2011-07-22
    相关资源
    最近更新 更多