33

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

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

4

5 回答 5

26

MSDN 解释了如何使用Pipe Handle Inheritance中的 Windows API 执行 popen 所做的事情。在这里,它提供了一个有据可查的示例。_popen它比Jason 链接的运行时库中的函数更底层,但只使用 Win32 API。

于 2009-01-16T16:12:55.717 回答
21

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

于 2009-01-16T16:07:19.893 回答
3

可悲的是,这并不是特别容易。

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

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

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

于 2009-01-19T21:38:38.547 回答
3

挖一个旧线程...

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

于 2012-11-27T01:49:51.430 回答
1

这是一篇旧文章,但几年前我还需要在 Windows 环境中使用类似popen()的调用。正如此处答案中的一些评论所指出的那样,使用 Windows API 来实现任何接近经典 POSIXpopen()的东西都很有趣。

我创建了一个提交给Code Review的实现。此实现使用pipestostdin和 fromstdout以及用于CreateProcess(...).

链接代码旨在构建到具有非常小的 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 窗口弹出窗口的情况下执行此操作。缓冲区根据需要增长以适应响应的大小。

于 2020-09-16T18:00:29.963 回答