I'm kind of new at Mac programming. I am porting a plugin to OSX. I need my application to launch a second app (which I do not control the source for) and then get its exit code. NSWorkspace launchApplicationAtURL works great to launch it with the needed arguments but I can't see how to get the exit code. Is there a way to get it after setting up notification for termination of the second app? I see tools for getting an exit code using NSTask instead. Should I be using that?
Asked
Active
Viewed 3,391 times
2 Answers
7
The NSWorkspace
methods are really for launching independent applications; use NSTask
to "run another program as a subprocess and ... monitor that program’s execution" as per the docs.
Here is a simple method to launch an executable and return its standard output - it blocks waiting for completion:
// Arguments:
// atPath: full pathname of executable
// arguments: array of arguments to pass, or nil if none
// Return:
// the standard output, or nil if any error
+ (NSString *) runCommand:(NSString *)atPath withArguments:(NSArray *)arguments
{
NSTask *task = [NSTask new];
NSPipe *pipe = [NSPipe new];
[task setStandardOutput:pipe]; // pipe standard output
[task setLaunchPath:atPath]; // set path
if(arguments != nil)
[task setArguments:arguments]; // set arguments
[task launch]; // execute
NSData *data = [[pipe fileHandleForReading] readDataToEndOfFile]; // read standard output
[task waitUntilExit]; // wait for completion
if ([task terminationStatus] != 0) // check termination status
return nil;
if (data == nil)
return nil;
return [NSString stringWithUTF8Data:data]; // return stdout as string
}
You may not want to block, especially if this is your main UI thread, supply standard input etc.

CRD
- 52,522
- 5
- 70
- 86
-
Thank you so much! I got a much more basic version working with NSTask but this is very useful. My confusion was with the relative purpose of NSTask vs NSWorkspace. Somehow I had gotten the impression that NSWorkspace was superceding NSTask. – Ben Mar 15 '11 at 15:11
-
Thanks, last line I changed to return [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease] because app crashed – Libor B. Nov 16 '17 at 14:24
1
In fact, this property of the NSTask should do the trick: terminationStatus
From Apple's doc:
Returns the exit status returned by the receiver’s executable.
- (int)terminationStatus
I tested it and it works ok. Watch out to test if the task is running first, otherwise an exception will be launched.
if (![aTask isRunning]) {
int status = [aTask terminationStatus];
if (status == ATASK_SUCCESS_VALUE)
NSLog(@"Task succeeded.");
else
NSLog(@"Task failed.");
}
Hope it helps.

Eric Giguere
- 766
- 5
- 9