Passing a file path into File::startAsProcess()


#1

Hey
I’m trying to use File::startAsProcess() to run a command line application that requires two parameters.
One of the parameters is a file path that will very likely include spaces, however passing in a String with spaces won’t be recognised as a single command line parameter and will cause errors. I’ve tried using the '\ ’ sequence as used within Terminal on OS X however this doesn’t solve anything.
How can I do this?

Also, a follow up question - when running a command line app this way it will return information into the console in Xcode. Is it possible to return this into a String variable so that I can use the data in some way, for example, display any errors to the user on my applications GUI?

Thanks.


#2

What you need is the ChildProcess-Class, the term “startAsProcess” is may a little bit unclear.


#3

Works like a treat. Thanks chkn!


#4

Actually, I’m unable to get the second part of my question working.

I’m using the ChildProcess object to run a bootloader app that takes a hex file and uploads it onto a USB board.
There are a number of errors I could get, such as “Unable to open device” or “Unspecified mmcu type”, which I would like to display to the user if they occur.

These are being displayed in my Xcode console however when calling readAllProcessOutput() it never seems to return anything.
Any ideas to why?


#5

I guess your console gets stderr, while stdout goes to readAllProcessOutput()

Try redirecting stderr to stdout in your command, ie
/path/to/command arg1 arg2 2>&1


#6

[quote=“grebneke”]Try redirecting stderr to stdout in your command, ie
/path/to/command arg1 arg2 2>&1[/quote]
My bad, the shell redirect above won’t work. I was thinking about File::startAsProcess() which in turn calls Process::openDocument() which then uses /bin/sh to open files.

ChildProcess forks and calls execvp() directly, bypassing /bin/sh. That is a good thing. However, currently ChildProcess will only read stdout from the forked process, and not stderr.

ChildProcess could easily be changed to also include stdout in readAllProcessOutput(), or provide a separate method to read stderr, thus allowing to separate normal output from errors.

The question is what Jules thinks. The easy path is to bundle stderr+stdout together in readAllProcessOutput(). If Jules agrees to that, I can help with a suggested patch to juce_core/native/juce_posix_sharedCode.h


#7

It’s about as simple as this:

[code]diff --git a/modules/juce_core/native/juce_posix_SharedCode.h b/modules/juce_core/native/juce_posix_SharedCode.h
index 4744ca6…b291627 100644
— a/modules/juce_core/native/juce_posix_SharedCode.h
+++ b/modules/juce_core/native/juce_posix_SharedCode.h
@@ -1005,6 +1005,7 @@ public:
// we’re the child process…
close (pipeHandles[0]); // close the read handle
dup2 (pipeHandles[1], 1); // turns the pipe into stdout

  •            dup2(pipeHandles[1], 2);  // redirect stderr to stdout
               close (pipeHandles[1]);
    
               Array<char*> argv;
    

[/code]


#8

[quote=“grebneke”]

[code]diff --git a/modules/juce_core/native/juce_posix_SharedCode.h b/modules/juce_core/native/juce_posix_SharedCode.h
index 4744ca6…b291627 100644
— a/modules/juce_core/native/juce_posix_SharedCode.h
+++ b/modules/juce_core/native/juce_posix_SharedCode.h
@@ -1005,6 +1005,7 @@ public:
// we’re the child process…
close (pipeHandles[0]); // close the read handle
dup2 (pipeHandles[1], 1); // turns the pipe into stdout

  •            dup2(pipeHandles[1], 2);  // redirect stderr to stdout
               close (pipeHandles[1]);
    
               Array<char*> argv;
    

[/code][/quote]

Added that and it’s all working great thanks! Would be useful if Jules could add this change.

Is this currently set up for Windows? The following lines (477-478) in juce_win32_Threads.h makes me believe so:

startupInfo.hStdError  = writePipe;
startupInfo.hStdOutput = writePipe;

#9

From testing I can confirm there is no issue on Windows.


#10

Thanks chaps, yes, it should indeed be using stderr like it does on Windows, I’ll get that sorted out!