【问题标题】:Getting the POSIX path of the Finder's front window获取 Finder 前窗的 POSIX 路径
【发布时间】:2010-11-06 03:03:24
【问题描述】:

如何获取当前位于其窗口列表顶部的 Finder 窗口的 POSIX 路径? 最好使用某种 Cocoa 框架,但我对任何事情都持开放态度。

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

[[NSWorkspace sharedWorkspace] subpathsAtPath:thePath]

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

[[NSWorkspace sharedWorkspace] selectFile:aFile inFileViewerRootedAtPath:thePath]

在一个循环中循环通过由 grep 返回的条目组成的 NSArray。

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

感谢您查看我的问题!

安德烈

PS:我不确定 grep 部分,也许我会在那里拍一下 RegexKit Lite...

【问题讨论】:

    标签: objective-c cocoa finder


    【解决方案1】:

    您可能可以通过 AppleScript 询问 Finder。

    这个*单行适用于我:

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

    *this 的修改版本。

    【讨论】:

    • 啊对...我完全忘记了 AppleScript。很高兴知道这是一个备用计划。您是否也碰巧知道在 Cocoa/Carbon 中处理这个问题的一两个指针?我想知道manytricks.com/witch 如何获得所有窗口的列表...感谢您写下这篇文章:)
    • 我不知道一个 Cocoa/Carbon 接口可以让我们检查另一个进程的窗口列表。即使可以,您如何确定它对应的路径?
    • 谢谢你,这正是我所追求的。我首先错过了到别名的转换。我试图做诸如“作为 POSIX 路径”而不是“作为别名”和“(窗口 1 的目标)的 POSIX 路径”之类的事情,但没有成功。让我感到困惑的是,您首先必须转换为别名..!
    【解决方案2】:

    我正在开发一个与您描述的完全一样的商业应用程序,并且一年多来我一直在尝试不同的方法。我是一名新手开发人员,所以我完全接受这样的想法,即可能有比我的方式更好的方法,但它似乎稳定且有效。

    我使用 Apple 脚本

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

    使用 Carbon 获取窗口列表

    要获取所有进程的窗口列表以获取窗口 ID(Apple Script 无法做到),我使用 CGWindowListCopyWindowInfo,如本问题所述:

    Getting a unique ID for a window of another application

    这为我提供了一个数组,其中包含最前面的所有进程的所有窗口。所以我需要做的就是从数组中取出第一个条目。如果这对您有帮助,这也可以用于获取前窗的屏幕抓图,如“抓斗之子”示例应用程序中所示,作为一个工作示例,这对我来说非常宝贵。

    从 Cocoa 发送 Apple 脚本

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

    1. Apple 活动管理器依赖于您 发送原始 Apple 事件。为了我, 这太像辛勤工作了 级别太低了。

    2. 我发现使用 NSAppleScript 速度慢且容易出错。这也是 当你想发送一个非常笨拙的 各种苹果脚本 和我一样发消息。

    3. 在阅读 Scripting Bridge 时, 我很兴奋,只是想尝试一下 出来并感到非常失望。为了 我是windows的属性 试图抓住,它甚至没有 承认它们是存在的。看起来 对我来说是越野车和奇怪的。我预计 如果您发送的命令是 由SB支持,这将是最好的 选项。

    第四个选项

    我现在依赖于 Apple Script 的出色 Objective C 包装器,名为 AppScript。它已经存在很多很多年了,它很稳定,开发人员很棒,而且最重要的是它可以正常工作。

    它拥有坚如磐石的方法,允许您发送 Apple Script,它甚至可以整齐地为您返回错误,而无需检查一大堆可能存在错误和混乱的代码。

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

    【讨论】:

    • 您好,感谢您的参与。您的解释以及漂亮的示例代码真的有很长的路要走。
    • 没问题。如果您还有其他问题,请随时更新此问题。
    • 嗨,约翰,感谢您的信息。我尝试了 SonOfGrab,它在最前面向我展示了很多“不相关”的窗口,比如菜单项等。你怎么知道哪个窗口真的是最前面的?
    • 有很多不同的方法可以做到这一点,具体取决于您想要做什么和您的限制。我使用 AppScript 并使用最前面进程的“AXFocusedWindow”或“AXMainWindow”:set theprocess to the first process whose frontmost is true 然后set thewindow to the value of attribute "AXFocusedWindow" of theprocessset thewindow to the value of attribute "AXMainWindow" of theprocess
    【解决方案3】:

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

    您的选择包括:

    • 直接使用 Apple 事件管理器(或 NSAppleEventDescriptor 和朋友)。
    • 使用 NSAppleScript 或 OSAScript 对象。
    • 使用 ScriptingBridge。

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

    【讨论】:

    • 感谢您的回复,先生!几个名字就足够了……将研究 AEM/OSAScript。如果它对我的设计师来说太复杂了,我可能会坚持备份计划:D 再次感谢你们俩。你的回答很有帮助。安德烈
    【解决方案4】:

    可以在 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)
    

    【讨论】:

      猜你喜欢
      • 2018-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 2017-12-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多