获取Finder前窗的POSIX路径

时间:2009-06-26 11:38:34

标签: objective-c cocoa finder

如何获取当前位于窗口列表顶部的Finder窗口的POSIX路径? 最好使用某种Cocoa框架,但我可以做任何事情。

背景: 我需要这个,因为我想选择匹配正则表达式模式的文件,从这个路径递归开始。想法是使用

[[NSWorkspace sharedWorkspace] subpathsAtPath:thePath]

获取此路径的所有后代的方法,在NSTask中使用“grep”(以避免打包正则表达式支持框架)并使用

[[NSWorkspace sharedWorkspace] selectFile:aFile inFileViewerRootedAtPath:thePath]
循环遍历由grep返回的条目生成的NSArray的循环中的

到目前为止,我已经在Xcode文档中查看了NSWorkspace,NSFileManager和NSApplication以及其他关键字搜索。

感谢您查看我的问题!

安德烈

PS:我不确定grep部分,也许我只是在那里拍RegexKit Lite ......

4 个答案:

答案 0 :(得分:5)

您可以通过AppleScript向Finder询问。

这个*单行为我工作:

osascript -e 'tell application "Finder" to set myname to POSIX path of (target of window 1 as alias)'

* this的修改版本。

答案 1 :(得分:3)

我正在开发一个商业应用程序,它完全符合您所描述的内容,而且我已经在使用不同的方法来实现这一目标超过一年了。我是一个新手开发者,所以我完全乐于接受这样的想法,即可能有一种更好的方式,而不是我的方式,但它似乎是稳定的并且有效。

我使用Apple脚本

我每3秒获取一次活动文档的路径,但如果活动应用程序是Finder,我会得到活动窗口的路径。我使用Apple脚本执行此操作,如接受的答案所述。

使用碳获取窗口列表

要获取所有进程的窗口列表以获取窗口ID(Apple Script无法做到的事情),我使用CGWindowListCopyWindowInfo,详见此问题:

Getting a unique ID for a window of another application

这给我一个数组,其中所有进程的所有窗口都是最前面的。所以我需要做的就是从数组中获取第一个条目。这也可用于获取前窗的屏幕抓取,如果这对你有帮助,如Son of Grab示例应用程序中所示,这对我来说是非常宝贵的工作示例。

从Cocoa发送Apple脚本

说到Apple Script,我已经尝试了Jim建议的所有3个,我的结论是每个都有问题,无论是在稳定性还是灵活性方面。

  1. Apple Event Manager依赖于您 发送原始Apple活动。为了我, 这太像是努力工作了 水平太低了。

  2. 使用我发现的NSAppleScript 缓慢且容易出错。这也是 当你想发送一个非常笨拙的时候 各种各样的Apple Script 和我一样的消息。

  3. 阅读Scripting Bridge时, 我非常兴奋,只是尝试一下 出去,非常失望。为了 我的窗口的属性 试图抓住,它甚至没有 认识到他们存在。看起来 让我变得越来越奇怪。我预计 如果您发送的命令是 SB支持,这将是最好的 选项。

  4. 第四个选项

    我现在依赖于名为AppScript的Apple Script的神话般的Objective C包装器。它已经存在很多年了,它很稳定,开发人员很棒,而且最重要的是它才有效。

    它有坚如磐石的方法,允许您发送Apple脚本,它甚至会为您整齐地返回错误,而不需要检查它们的潜在错误和杂乱的代码。

    我已经使用它一年了,没有任何问题。如果您对如何执行此操作有任何其他疑问,请随时发表评论,我会尽力回答。

答案 2 :(得分:2)

获取Finder中最前面窗口所代表的POSIX路径将涉及以某种方式将Apple事件发送到Finder。

您的选择包括:

  • 直接使用Apple Event Manager(或NSAppleEventDescriptor和朋友)。
  • 使用NSAppleScript或OSAScript对象。
  • 使用ScriptingBridge。

如果您正在构建Cocoa应用程序,OSAScript可能是最自然的选择。

答案 3 :(得分:0)

可以在Swift 4中使用ScriptingBridge

import Foundation
import ScriptingBridge // imports: ScriptingBridge.SBApplication, .SBElementArray, .SBObject

// SBApplication? to SBApplication to FinderApplication
let finder = (SBApplication(bundleIdentifier: "com.apple.finder")!) as FinderApplication

let windowList: SBElementArray = finder.windows!()
guard windowList.count > 0,
    let window = windowList[0] as? FinderWindow,
    let windowProperties = window.properties,
    let windowTarget = windowProperties["target"] as? FinderFolder,
    let windowUrlOptionalStr = windowTarget.URL,
    let windowUrlSubStr = windowUrlOptionalStr
        .removingPercentEncoding?
        .dropFirst(7) // "file://" 7 characters
else {
    // … handle failure
}

let windowUrl = URL(
    fileURLWithPath: String(windowUrlSubStr),
    isDirectory: true,
    relativeTo: nil)