0

I want to create a cocoa app to call command line tool written use c++. I can do it well when use Xcode to call command line tool. but It fail when I close Xcode, double click the app and press Update button to run command line tool. I've tired to use NSTask to call command line tool but it still fail. These is my code.

- (IBAction)Update:(id)sender {

[self performSelectorOnMainThread:@selector(IspUpdate) withObject:nil waitUntilDone:YES];
}

-(void)IspUpdate {
strCurDir = [[NSBundle mainBundle] bundlePath];
NSRange range = [strCurDir rangeOfString:@"/" options:NSBackwardsSearch];
NSRange rangeDir = NSMakeRange(0, range.location + 1);
strCurDir = [strCurDir substringWithRange:rangeDir];

NSString *strCmd = [strCurDir stringByAppendingString:@"ISPTool --isp --fw fw.bin --comm 6"];


dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{

system([strCmd UTF8String]);
});
}
  • Show the code you tried that uses the `Process` (`NSTask`) class. The `Process` class is how you run a command-line program from a Cocoa app. Update your question with this code and the errors that occur when you try to call the command-line program. – Swift Dev Journal Nov 11 '20 at 22:18
  • 1. Launch your app by opening the executable in appBundle/Contents/MacOS with a launchPath of /usr/bin/open followed by args of executable path. 2. Then use the update button to run another NSTask this time using a launch path of /bin/sh to add the command to the first Terminal window. – apodidae Nov 11 '20 at 23:07

1 Answers1

0

Please run this demo and see if it is similar to what you are trying to do. The code will allow you to run NSTask in the app's terminal window by clicking a button. Save the following code in a file called 'runCmd.m' and then compile from the command line using the instructions given below:

/*
 Run from Terminal using: clang runCmd.m -fobjc-arc -framework Cocoa -o runCmd && ./runCmd
 Should print current calendar when 'RunCommand' button is hit.
*/

#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate> {
 NSWindow *window;
}
 -(void) runMyCmd;
 -(void) buildMenu;
 -(void) buildWindow;
@end

@implementation AppDelegate

- (void) runMyCmd {
 NSTask *task = [[NSTask alloc] init];
 [task setLaunchPath: @"/bin/sh"]; 
 NSArray *args = [NSArray arrayWithObjects: @"-c", @"cal", nil];
 [task setArguments: args];
 NSPipe *pipe = [NSPipe pipe];
 [task setStandardOutput: pipe];
 [task launch];
 [task waitUntilExit];
 NSData *data = [[pipe fileHandleForReading] readDataToEndOfFile];
 NSString *string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
 NSLog (@"\n%@",string);
}

- (void) buildMenu {
 NSMenu *menubar = [NSMenu new];
 NSMenuItem *menuBarItem = [NSMenuItem new];
 [menubar addItem:menuBarItem];
 [NSApp setMainMenu:menubar];
 NSMenu *appMenu = [NSMenu new];
 NSMenuItem *quitMenuItem = [[NSMenuItem alloc] initWithTitle:@"Quit"
 action:@selector(terminate:) keyEquivalent:@"q"];
 [appMenu addItem:quitMenuItem];
 [menuBarItem setSubmenu:appMenu];
}

- (void) buildWindow {

 #define _wndW  200
 #define _wndH  150

 window = [[NSWindow alloc] initWithContentRect: NSMakeRect( 0, 0, _wndW, _wndH )
 styleMask: NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable
 backing: NSBackingStoreBuffered defer: NO];
 [window center];
 [window setTitle: @"Test window"];
 [window makeKeyAndOrderFront: nil];

// **** RunCmdButton **** //
 NSButton *runBtn =[[NSButton alloc]initWithFrame:NSMakeRect( 30, 60, 135, 30 )];
 [runBtn setBezelStyle:NSBezelStyleRounded ];
 [runBtn setTitle: @"RunCommand"];
 [runBtn setAction: @selector(runMyCmd)];
 [[window contentView] addSubview: runBtn];

// **** Quit btn **** //
 NSButton *quitBtn = [[NSButton alloc]initWithFrame:NSMakeRect( _wndW - 50, 5, 40, 40 )];
 [quitBtn setBezelStyle:NSBezelStyleCircular ];
 [quitBtn setTitle: @"Q" ];
 [quitBtn setAutoresizingMask: NSViewMinXMargin];
 [quitBtn setAction:@selector(terminate:)];
 [[window contentView] addSubview: quitBtn];
}

- (void) applicationWillFinishLaunching: (NSNotification *)notification {
 [self buildMenu];
 [self buildWindow];
}

- (void) applicationDidFinishLaunching: (NSNotification *)notification {
}

@end

int main () {
 NSApplication *application = [NSApplication sharedApplication];
 AppDelegate *appDelegate = [[AppDelegate alloc] init];
 [application setDelegate:appDelegate];
 [application run];
 return 0;
}


apodidae
  • 1,988
  • 2
  • 5
  • 9