有没有办法在Finder中确定当前活动的窗口或文件夹?在某种意义上,我需要这个来确定一个适当的"默认"位置,在该位置可以在我的应用中执行某些特定的操作.
实际上,这个问题是否有意义?这个"当前活动的Finder窗口/文件夹"的概念是否首先存在?如果没有,我请问如何获取当前选择的 Finder项目.
是的,当前活动的Finder窗口的概念确实存在,以及当前选定的项目.
例如,以下AppleScript获取selection最前面窗口中的当前选择.由于这会返回一个文件或文件夹列表,即使只有一个项目,下一行也会从该列表中获取第一个项目(在确保列表的计数大于0之后).然后,您可以向Finder询问container window所选项目,该项目将返回一个Finder window对象.
tell application "Finder"
set selectedItems to selection
if ((count of selectedItems) > 0) then
set selectedItem to (item 1 of selectedItems) as alias
container window of selectedItem
end if
end tell
Run Code Online (Sandbox Code Playgroud)
我很确定发布的代码sidyll在10.5及更早版本中可以正常工作,但由于AppleScript似乎从一个版本的OS X到下一个版本的不可避免的变化和怪癖,它在10.6中出错.
[编辑]实际上,我只知道发生了什么.我通常一直打开Finder的Inspector窗口(通过Command-Option-i获得的动态Get Info窗口),右上图显示在下图中:

该图像显示了3种不同的窗口:
1)左上角是一个Get Info窗口information window,它继承自泛型window类.
2)右上角是一个Inspector窗口,是一个平原window.
3)下图显示了a Finder window,它继承自泛型window类.
如果我使用上面显示的窗口设置运行以下脚本:
tell app "Finder"
every window
end tell
Run Code Online (Sandbox Code Playgroud)
它返回以下结果:
{ 窗口 "mdouma46信息"的应用程序 "发现者",信息窗口 "mdouma46信息"的应用程序 "发现者",Finder窗口 ID的1141 应用程序 "发现者"}
因此,在我的情况下发生的事情是,由于Inspector窗口是一个浮动的实用工具面板,如果它当前正在显示,要求Finder window 1将始终返回Inspector面板,因为它总是浮动在其他窗口的前面.
所以运行代码时我得到的错误是:
错误"无法将应用程序\"Finder \"的窗口1的"类fvtg"转换为类型别名." 数字-1700从窗口1的«class fvtg»到别名
(换句话说,Inspector窗口,一个普通的window,没有FileViewer target(fvtg)属性;只有Finder windows).
因此,只要用户没有Inspector窗口,Preferences窗口或最前面的Get Info窗口,您的代码就可以正常工作.但是,通过更改window为Finder window,您可以确保只查看具有该target属性的文件查看器窗口.
所以,像这样:
NSDictionary *errorMessage = nil;
NSAppleScript *script = [[[NSAppleScript alloc] initWithSource:
@"tell application \"Finder\"\n"
" if ((count of Finder windows) > 0) then\n"
" return (POSIX path of (target of Finder window 1 as alias))\n"
"end if\n"
"end tell"] autorelease];
if (script == nil) {
NSLog(@"failed to create script!");
return nil;
}
NSAppleEventDescriptor *result = [script executeAndReturnError:&errorMessage];
if (result) {
// POSIX path returns trailing /'s, so standardize the path
NSString *path = [[result stringValue] stringByStandardizingPath];
return path;
}
Run Code Online (Sandbox Code Playgroud)