10

I have seen this thread on how to execute terminal commands from within a Cocoa app. But I want to actually launch Terminal.app to a specified directory.

I know that the following does not work:

[[NSWorkspace sharedWorkspace] openFile:folderPath withApplication:@"Terminal"];

Terminal tries to actually open the folder as a file.

Is this something I have to use AppleScript for?

Any ideas?

Corey Floyd
  • 25,929
  • 31
  • 126
  • 154

5 Answers5

14

You could use AppleScript from Cocoa like this:

NSString *s = [NSString stringWithFormat:
     @"tell application \"Terminal\" to do script \"cd %@\"", folderPath];

NSAppleScript *as = [[NSAppleScript alloc] initWithSource: s];
[as executeAndReturnError:nil];

AppleScript script was taken from cobbal. Thanks mate!

Woofy
  • 3,751
  • 1
  • 14
  • 12
  • 1
    Although perhaps overkill for this use, the Scripting Bridge (http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ScriptingBridgeConcepts/Introduction/Introduction.html) is a good solution for communicating with external apps via AppleScript from within Objective-C apps. – Barry Wark Sep 19 '09 at 02:28
  • be careful of folders with a quotation marks or spaces in them though – cobbal Sep 19 '09 at 04:40
  • Is there any way to not showing the Terminal App? Can Scripting Bridge achieve this behaviour? – swdev Sep 13 '14 at 03:04
  • 1
    The folder path must be quoted like this or this command won't work correctly: `@"tell application \"Terminal\" to do script \"cd \\\"%@\\\"\""` – Pol Mar 22 '15 at 02:14
2

Not sure if there's a way to do it in plain cocoa, but in applescript it's fairly trivial

tell application "Terminal" to do script "cd ~/Desktop"
cobbal
  • 69,903
  • 20
  • 143
  • 156
0

The existing answers suggesting using the cd command are great. Additionally, I recommend checking out the source to the app cdto for a great example. Cdto is a fast mini application that opens a Terminal.app window cd'd to the front most finder window. This app is designed (including it's icon) to placed in the finder window's toolbar.

Joey Hagedorn
  • 2,408
  • 19
  • 22
0

You can use the (now obsolete) AppleEvent Carbon API to send an "Do Script" event to Terminal.app :

OSStatus doTerminalScript (NSString* script) {
    AppleEvent evt;
    OSStatus err;
        // Build event
    err = AEBuildAppleEvent(kAECoreSuite, kAEDoScript, 
                            typeApplicationBundleID, "com.apple.terminal", 18L,
                            kAutoGenerateReturnID, kAnyTransactionID, &evt, NULL,
                            "'----':utf8(@)", strlen([script UTF8String]), [script UTF8String]);
    if (err) return err;
    AppleEvent res;
        // Send event
    err = AESendMessage(&evt, &res, kAEWaitReply, kAEDefaultTimeout);
    AEDisposeDesc(&evt);
    if (err) return err;
        // Check for any errors from Terminal.app
    AEDesc desc;
    err = AEGetParamDesc(&res, keyErrorNumber, typeSInt32, &desc);
    AEDisposeDesc(&res);
    if (!err) {
        AEGetDescData(&desc, &err, sizeof(err));
        AEDisposeDesc(&desc);
    } else if (err == errAEDescNotFound)
        err = noErr;
    return err;
}

Taken form here. Note that Terminal.app must be launched with -[NSWorkspace launchApplication:] if not running. If wanted, it can be put in foreground with - [NSApplication activateWithOptions:]

As suggested by a comment, this can be easily ported to the more modern Scripting Bridge API.

Félix Faisant
  • 191
  • 1
  • 1
  • 11
-1

I don't really know AppleScript, but I bet you could use it for this.

If the terminal directory is the same each time, you could just make an executeable .sh file with a cd command in it and make that the openFile argument.

phoebus
  • 14,673
  • 2
  • 33
  • 35