Reputation: 3603
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
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
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
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