【问题标题】:What is the equivalent to Posix popen() in the Win32 API?Win32 API 中的 Posix popen() 等价物是什么?
【发布时间】:2010-10-01 20:10:19
【问题描述】:

Win32 API 中是否有与 Linux/Unix stdio.h popen() 函数大致等效的函数?如果有,在哪里可以找到?

编辑:我需要知道这一点来修补 D 标准库中的一个遗漏。任何答案都必须使用标准 Win32 API,不得使用特定于 MSVC 的函数。另外,如果存在的话,我更喜欢不是非常低级的东西。

【问题讨论】:

  • _popen 是 Windows 上标准 C 库的一部分,任何链接/使用标准 C 库的人都可以使用。
  • 好的,我似乎无法从支持 C ABI 的 D 中得到它,但这可能超出了这个问题的范围。
  • Windows 不是 Linux;操作系统中没有标准 C 库。 KERNEL32.DLL 没有 printf()

标签: c linux winapi api posix


【解决方案1】:

MSDN 在 Pipe Handle Inheritance 中解释了如何使用 Windows API 来完成 popen 的工作。 Here 它提供了一个有据可查的示例。它比 Jason 链接的运行时库中的 _popen 函数更底层,但只使用 Win32 API。

【讨论】:

  • 哦,我比我更喜欢这个答案:)
  • 看起来很有趣,如果我的交货期限没有迟到 2 天,我可能有兴趣实施这个解决方案 :-) 。但对于我的需要(我只想捕获标准输出),_popen 绰绰有余。
  • 您是否忘记发布指向 MSDN 页面的链接?这个有据可查的例子在哪里?
【解决方案2】:

如果您正在编写控制台应用程序,您可以致电_popen。有关详细信息,请参阅 MSDN 站点上的文档:http://msdn.microsoft.com/en-us/library/96ayss4b(VS.80).aspx

【讨论】:

  • 我也喜欢你的,伙计。直接符合我认为的那个人想要的:)
  • 请注意,这不会处理路径中的空格 :(
【解决方案3】:

遗憾的是,这并不是特别容易。

您需要使用 win32 函数 (CreatePipe) 创建管道,然后通常需要复制您提供给子进程的管道末端 (DuplicateHandle) 以允许其被继承,否则它将不会t be,因此不能使用。

然后你需要使用 CreateProcess 创建一个进程(它需要很多结构指针,包括一个 STARTUPINFO),并将你复制的句柄作为它的标准输出传递给 STARTUPINFO。

然后您可以从管道的读取端(ReadFile 等)读取直到到达 eof,然后您需要通过关闭所有各种 win32 句柄来进行清理。

【讨论】:

    【解决方案4】:

    挖掘一个旧线程......

    回应 Jason Coco 的上述回复,与链接的 MSDN 页面声称的相反,现在显然可以从非控制台应用程序调用 _popen()。我从一个 QuickTime 导入器组件中调用它,基本上是一个伪装的 DLL。它会打开一个控制台窗口,但会显示预期的行为。使用 mingw32 的 -mwindows 选项编译标准控制台工具以使其成为 GUI 应用程序,_popen 继续正常工作(但即使从另一个控制台运行该工具也会打开一个控制台窗口。

    【讨论】:

      【解决方案5】:

      这是一篇旧帖子,但几年前我还需要在 Windows 环境中使用 popen() 之类的调用。正如此处答案中的几个 cmets 所指出的,使用 Windows API 来实现任何接近经典 POSIX popen() 的东西很有趣。

      我创建了一个实现并提交给Code Review 。此实现使用pipesstdinstdout,以及CreateProcess(...) 的Windows 方法。

      链接代码被设计成使用非常小的 API 构建到 dll 中。

      int __declspec(dllexport) cmd_rsp(const char *command, char **chunk, unsigned int size); 
      

      简单的用法示例:

      #include "cmd_rsp.h"
      int main(void)
      {
          char *buf = {0};
          buf = calloc(100, 1);
          if(!buf)return 0;
          cmd_rsp("dir /s", &buf, 100);
          printf("%s", buf);
          free(buf);
          //or a custom exe
          char *buf2 = {0};
          buf2 = calloc(100, 1);
          cmd_rsp("some_custom_program.exe arg_1 arg_2 arg_n", &buf2, 100);
          printf("%s", buf2);
          free(buf2);
          
          return 0;
      }
      

      它接受任何可以从stdin 发出的命令,创建一个单独的进程来执行命令,然后将所有响应内容(如果有的话)返回到缓冲区,并且在不显示 CMD 窗口的情况下执行此操作弹出窗口。缓冲区会根据需要增长以适应响应的大小。

      【讨论】:

        猜你喜欢
        • 2017-04-04
        • 1970-01-01
        • 2016-06-25
        • 2011-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-04
        • 1970-01-01
        相关资源
        最近更新 更多