获取Finder前窗的POSIX路径

问题描述 投票:3回答:4

如何获取当前位于窗口列表顶部的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 ......

objective-c cocoa finder
4个回答
3
投票

我正在开发一个商业应用程序,它完全按照你描述的方式进行,并且我已经用不同的方式搞乱了一年多。我是一个新手开发人员,所以我完全乐于接受这样的想法,即可能有一种更好的方式,而不是我的方式,但它似乎是稳定和有效的。

我使用Apple Script

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

使用Carbon获取窗口列表

要获取所有进程的窗口列表以获取窗口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 Events。对我来说,这太像是努力工作和太低级别。
  2. 使用NSAppleScript我发现速度慢且容易出错。当你想像我一样发送各种Apple Script消息时,它也非常笨拙。
  3. 在阅读有关Scripting Bridge的内容时,我非常兴奋,只是尝试一下并非常失望。对于我试图抓住的窗口的属性,它甚至没有将它们识别为存在。在我看来,这是多么多的怪异和怪异。我希望如果你发送的命令得到SB的支持,那将是最好的选择。

第四种选择

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

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

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


5
投票

您可以通过AppleScript向Finder询问此问题。

这个*单行为我工作:

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

* this的修改版本。


2
投票

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

您的选择包括:

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

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


0
投票

可以将ScriptingBridge与Swift 4一起使用

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)
© www.soinside.com 2019 - 2024. All rights reserved.