Multi-instance console app output (std::cout)

I have a JUCE gui based app which I have converted to console app (by adding _CONSOLE #define, a main.cpp and not launching the gui thread). This works fine, and I can use command line parameters, and print output to the console (cmd.exe or powershell) using the typical std::cout.

However, this console app is to be used as endpoints by php script and I’ve run into a couple issues, including perhaps my own confusion about how to direct the output to the calling php/thread/endpoint.

Issue/Question #1:
The first instance of the app directs the output to std::cout fine. When the same exe is called from command line with another command, I can step into anotherInstanceStarted as expected, but of course the new instance exits almost immediately as the new command/thread is started in the main process loop, and as such all output for this new ‘session’ is redirected to the main instance std::cout. Is there a way in JUCE to grab the handle of subsequent calling instance to redirect output to the proper endpoint?

Issue/Question #2:
In an effort to work around the above issue, I’ve attempted to implement ChildProcess class for all subsequent commands to the main.exe, again via anotherInstanceStarted. But again while the childProcess starts up fine, I am unable to read the output let alone redirect it to caller. In this case, regardless of whether I call readProcessOutput or readAllProcessOutput, those calls are blocking calls and do not return until the childProcess ends… the whole point of reading the output via a thread/loop is to get status/progress from the child process while it’s running. I’m about to try ChildProcessMaster/Slave implementations in hopes they’re more robust, but I have a suspicion this still won’t solve the issue of redirecting the std::cout to the corresponding handle.

Issue/Question #3:
I’m also a bit confused as to how to properly shut down a console app… closing the console window or ctrl-c doesn’t seem to call destruction properly (isn’t calling quit() / applicationRequestedQuit(), etc.) which I suppose usually happens via a gui close button… but is that the only case?

Even without the GUI window, if you want to use asynchronous features you need to run the MessageManager.

You should add ScopedJuceInitialiser_GUI as the first call in your main:

int main (int argc, char** argv)
{
    juce::ScopedJuceInitialiser_GUI initialiser;
    // ...

Thanks, the message manager is running… the first line is exactly that… but as far as shutdown goes, a quit() message is never received when closing the console window (via X or ctrl-c). And it would seem that as far as attempting to get a pointer on the console window handle when calling the console.exe a subsequent time with a new command, the handle has already been released by the time I break into main again. I was trying to get the handle to see if I could use it to properly redirect the console output… but I’m not sure this is the way to do it? or even possible?

Oh I see. Yes, when you close the terminal of a console application, it is usually simply killed. There is no callback (well, no default. I think you can catch the SIG_KILL on posix platforms).

As far as redirecting the stdout to the proper console window, there’s this bit of strangeness which seems to attempt to do the same if a gui app was launched from console… I’m wondering if the same can be used to ensure another console is started for the existing app?

#if JUCE_WINDOWS && JUCE_STANDALONE_APPLICATION && (! defined (_CONSOLE)) && (! JUCE_MINGW)
if (AttachConsole (ATTACH_PARENT_PROCESS) != 0)
{
    // if we've launched a GUI app from cmd.exe or PowerShell, we need this to enable printf etc.
    // However, only reassign stdout, stderr, stdin if they have not been already opened by
    // a redirect or similar.
    FILE* ignore;

    if (_fileno(stdout) < 0) freopen_s (&ignore, "CONOUT$", "w", stdout);
    if (_fileno(stderr) < 0) freopen_s (&ignore, "CONOUT$", "w", stderr);
    if (_fileno(stdin)  < 0) freopen_s (&ignore, "CONIN$",  "r", stdin);
}

#endif