fikovnik
fikovnik

Reputation: 3603

Get current directory of a Finder window from a cocoa application

I'm trying to get a current directory of a finder window that is in focus from another cocoa application that is running in a background. I know that it can be done using an applescript like:

tell application "Finder"
try
  set dir to (the target of the front window) as alias
on error
  set dir to startup disk
end try
end tell

However I was wondering whether there is some more generic way of doing it either using the accessibility API or some other UI scripting with perhaps System Event?

I tried attributes like NSAccessibilityDocumentAttribute or NSAccessibilityURLAttribute but none is set. From other mostly document based applications this works pretty well, but not for finder nor for terminal.app.

Upvotes: 4

Views: 1546

Answers (3)

geowar
geowar

Reputation: 4457

    // this is the finder
    FinderApplication * finder = [SBApplication applicationWithBundleIdentifier:@"com.apple.Finder"];
    // get all the finder windows
    SBElementArray * finderWindows = finder.FinderWindows;
    // this is the front window
    FinderWindow * finderWindow = finderWindows[0];
    // this is its folder
    FinderFolder * finderFolder = finderWindow.properties[@"target"];
    // this is its URL
    NSString * finderFolderURL = finderFolder.URL;
    NSLog(@"front window URL: %@", finderFolderURL);

Upvotes: 4

regulus6633
regulus6633

Reputation: 19040

@nkuyu, I just saw your comment that you know how to run an applescript... but for others who don't (and might stumble onto this post) I'll explain.

It's easy to run an applescript from objc using NSApplescript. And if you return a string from your applescript it's even easier to get a result because you can get the "stringValue" from the NSAppleEventDescriptor. As such I return "posix paths" from the applescript. Note that NSApplescript is not thread-safe so in multi-threaded apps you must take care to always run it on the main thread. Try this...

-(IBAction)runApplescript:(id)sender {
    [self performSelectorOnMainThread:@selector(getFrontFinderWindowTarget) withObject:nil waitUntilDone:NO];
}

-(void)getFrontFinderWindowTarget {
    NSString* theTarget = nil;
    NSString* cmd = @"tell application \"Finder\"\ntry\nset dir to the target of the front window\nreturn POSIX path of (dir as text)\non error\nreturn \"/\"\nend try\nend tell";
    NSAppleScript* theScript = [[NSAppleScript alloc] initWithSource:cmd];

    NSDictionary* errorDict = nil;
    NSAppleEventDescriptor* result = [theScript executeAndReturnError:&errorDict];
    [theScript release];
    if (errorDict) {
        theTarget = [NSString stringWithFormat:@"Error:%@ %@", [errorDict valueForKey:@"NSAppleScriptErrorNumber"], [errorDict valueForKey:@"NSAppleScriptErrorMessage"]];
    } else {
        theTarget = [result stringValue];
    }
    [self getFrontFinderWindowTargetResult:theTarget];
}

-(void)getFrontFinderWindowTargetResult:(NSString*)result {
    NSLog(@"result: %@", result);
}

Upvotes: 1

Brian Webster
Brian Webster

Reputation: 12055

Take a look at the Scripting Bridge framework, that's probably going to be the easiest way to get the info you want directly from your Cocoa application.

Upvotes: 2

Related Questions