1

I've spent the better part of a week searching for an answer to this (I thought) simple question, and while I've found many others with it, I have not yet found a clear answer, or even anything I could get to work.

My question is this: How can I invoke a child process, and read silently from its stdout pipe into a string, array, or something in the parent process without spawning a floating console window?

So far I have this code borrowed and tweaked slightly:

wls EXEC(string comm) {
    wls _internal;
    FILE* pipe = popen(comm.c_str(), "r");

    if (!pipe)
        return _internal;
    char buffer[8192];

    while (!feof(pipe))
        if (fgets(buffer, 8192, pipe) != NULL)
            _internal.push_back(ATS(buffer).substr(0, ATS(buffer).size() - 1));
    pclose(pipe);
    return _internal;
}

Important background info:

wls is the result of typedef vector<string> wls;

ATS is a template function I use to pass all sorts of things in and get back a string

Now, this function works perfectly, if we're talking function vs. form. It runs the child process, and I get back an array of strings - one for each line of the child process's output. However, every time it runs, it makes a command prompt window open. I understand that there is no way to avoid this with popen, so I have turned to CreateProcess(). I have not however managed to create an equivilant function to the one above using CreateProcess, and this is what I would like to do.

Could anyone possibly lend a hand? It would be much appreciated, and you would be creating the definitive guide for doing this anywhere on the internet if you are successful :)

Ken White
  • 123,280
  • 14
  • 225
  • 444
  • Though the question isn't (quite) a dupe, my [answer to a previous question](http://stackoverflow.com/a/5488264/179910) should satisfy your needs (although the code is undoubtedly a lot longer than you'd like--it's certainly longer than I'd like, anyway). – Jerry Coffin Sep 11 '15 at 22:32
  • Amazingly, I haven't yet seen that page. I'll have a go at it and post when I have some findings. Thanks! – Ryan Vickers Sep 11 '15 at 22:41
  • I actually have stumbled onto a very different (and vastly simpler) approach to solving this problem as a result of your link. I'm going to edit my original question to reflect my solution. – Ryan Vickers Sep 11 '15 at 23:05
  • Don't edit the question to reflect your solution. Post an answer instead. (Answering your own question is both permitted and encouraged.) – Keith Thompson Sep 11 '15 at 23:26
  • I've rolled back your edit. Adding *Solved* and the solution in your question is inappropriate. If you want to share the solution you found, write an answer to do so. See [Can I answer my own question?](http://stackoverflow.com/help/self-answer) for details on how to do so. – Ken White Sep 11 '15 at 23:29

1 Answers1

1

Sorry, I guess I should have posted an answer like this instead. Well here it is:

By adding just 2 extra lines of code, I've been able to solve my problem while continuing to use the function (with popen) I already had. If you require absolutely no popups, this won't be good enough for you, but if you can deal with just 1 incredibly brief popup, and nothing ever again after that, this if probably your best answer since it's much shorter than any of the "solutions" I've seen that use CreateProcess (and unlike all of them this actually worked for me first time and very easily).

Add the following 2 lines to the top of the main function of your graphical program:

AllocConsole();
ShowWindow(GetConsoleWindow(), SW_HIDE);

The first one creates and associates a console window with your program. The next line immediately hides it. This does create a popup (an extremely brief one), but since there is now a console window for your application, any and all calls to popen are able to exist in it, rather than creating their own window each and every time.