What is the equivalent to Posix popen() in the Win32 API?
Is there a rough equivalent to the Linux/Unix stdio.h popen() function in the Win32 API? If so, where can I find it?
Edit: I need to know this to patch an omission in the D standard library. Any answer must use only standard Win32 API, no MSVC-specific functions. Also, I'd prefer something that's not horribly low-level, if it exists.
MSDN explains how you do what popen does using the Windows API in Pipe Handle Inheritance . Here it provides a well-documented example. It's way more low-level than the _popen
function found in the runtime library linked by Jason, but uses the Win32 API exclusively.
You can call _popen
if you're writing a console application. For more information, see the documentation on the MSDN site: http://msdn.microsoft.com/en-us/library/96ayss4b(VS.80).aspx
Sadly it's not particularly easy.
You need to create a pipe using the win32 function (CreatePipe), then typically you need to duplicate the end of the pipe (DuplicateHandle) that you're giving to the subprocess to allow it to be inherited, otherwise it won't be and hence can't be used.
Then you need to create a process using CreateProcess (which takes lots of structure pointers, including a STARTUPINFO), and pass in the STARTUPINFO the handle that you've duplicated as its stdout.
Then you can read from the reading end of the pipe (ReadFile etc) until you reach eof, then you need to clean up by closing all the various win32 handles.
Digging up an old thread ...
Reacting to Jason Coco's reply above, and contrary to what the linked MSDN page claims, it is apparently possible nowadays to call _popen() from non-console apps. I call it from a QuickTime importer component, basically a DLL in disguise. It opens a console window but otherwise shows the expected behaviour. Compiling a standard console tool with mingw32's -mwindows option to make it a GUI app, _popen continues to work correctly (but a console window opens even when running the tool from another console.
This is an old post, but I also had a need several years ago to use a popen() like call in a Windows environment. As several of the comments in the answer here have noted, using the Windows API to implement anything close to the classic POSIX popen()
is interesting.
I created an implementation which I submitted to Code Review . This implementation uses pipes
to stdin
and from stdout
, as well as Windows methods for CreateProcess(...)
.
The linked code is designed to be built into a dll with a very small API.
int __declspec(dllexport) cmd_rsp(const char *command, char **chunk, unsigned int size);
Simple example of usage:
#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;
}
It takes any command that can be for example issued from stdin
, creates a separate process to execute the command, then returns all response content (If there is any) to a buffer, and does this without displaying the CMD window popup. The buffer grows as needed to accommodate size of response.