Andrew
Andrew

Reputation: 11427

How to open single "Get Info window" for several/multiple files/dirs?

I have a code:

func openGetInfoWnd(for urls: [URL]) {
    let pBoard = NSPasteboard(name: NSPasteboard.Name(rawValue: "pasteBoard_\(UUID().uuidString )") )
    
    pBoard.writeObjects(urls as [NSPasteboardWriting])
    
    NSPerformService("Finder/Show Info", pBoard)
}

this code opens multiple windows of Finder's "Get Info"

like it displays on Cmd + I hotkey

How can I open single one window ("Show Inspector" / "Get Info" / "Multiple Item Info") for multiple local urls?

Like it displayed on Cmd + Option + I press in Finder

enter image description here

PS: code: NSPerformService("Finder/Show Inspector", pBoard) ofc does not work :)

Upvotes: 0

Views: 354

Answers (2)

AgentBilly
AgentBilly

Reputation: 816

NSAppleScriptErrorNumber: -600 is a sandbox issue, to fix it (tested in Xcode 14.3):

  1. Go to [Your Project] > [Your Target] > Signing & Capabilities.
  2. Delete App Sandbox.
  3. Under Hardened Runtime (add the capability first by clicking + Capability if necessary), check "Apple Events".
  4. Add NSAppleEventsUsageDescription to your Info.plist.

Using @kakaiikaka's answer,

func openGetInfoWnd(for urls: [URL]) {
    let fileList = urls.map { "POSIX file \"\($0.absoluteString)\"" }
    let source = """
set fileList to {\(fileList.joined(separator: ", "))}
tell application "Finder"
    activate
    set selection to fileList
    tell application "System Events"
        keystroke "i" using {command down, option down}
    end tell
end tell
"""
    let appleScript = NSAppleScript(source: source)!
    var error: NSDictionary?
    appleScript.executeAndReturnError(&error)
    
    // ...
}

Rebuild your app (clean build + run) and it should now ask for permissions to send keystrokes to Finder. You'll likely see these pop-ups:

  • Asking for permission to access the directories (the urls with which the function is invoked).
  • Asking for permission to control "Finder" and "System Events" (separate pop-ups with the message you specified for the key NSAppleEventsUsageDescription).
  • Asking for Accessibility Access (you'll have to go to System Settings > Privacy & Security > Accessibility to grant access).

Now everything should work! :)

P.S. If you get a message saying "This method should not be called on the main thread as it may lead to UI unresponsiveness.", just do:

DispatchQueue(label: "AppleScript").async {
    // execute the applescript here instead...
}

(you can also set qos = .background if you want, but either way should work)

Upvotes: 2

kakaiikaka
kakaiikaka

Reputation: 4487

Tried many ways, you are right, NSPerformService is very limited, and cannot achieve it. And I also tried Apple Script's approach:

tell application "Finder" to open information window of file aFile

But that only works for the single file and there is no open "multiple information window" thing in Finder.

Luckily, your keyboard shortcuts remind me that I can simulate the file selection and keyboard keydown events.

So I believe below apple script can help you:

set fileList to {POSIX file "/Users/0x67/Downloads/new.html", POSIX file "/Users/0x67/Pictures/tt/00003-771884301.png"}

tell application "Finder"
    activate
    set selection to fileList
    tell application "System Events"
        keystroke "i" using {command down, option down}
    end tell
end tell

enter image description here

I think you can call this create this apple script in Swift and call it.

Here is a useful link to call it in swift:

Upvotes: 2

Related Questions