Wie schließe ich ein Fenster einer Anwendung und übergebe den Dateinamen?

Wie schließe ich ein Fenster einer Anwendung und übergebe den Dateinamen?

Ich versuche, einen Applescript-basierten Shell-Befehl zu erstellen, der der Vorschau-Anwendung von Mac OS X mitteilt, ein bestimmtes Fenster zu schließen.

#!/bin/sh

osascript <<EOF
tell application "Preview"
   close "$1"
end tell
EOF

Aber das funktioniert nicht: Ich erhalte die Fehlermeldung

25:52: execution error: Preview got an error: "musixdoc.pdf" doesn’t understand the close message. (-1708)

Verwandte Frage:Wie schließe ich eine OS X-Anwendung über die Befehlszeile mithilfe eines in meinem .bash_profile definierten Alias?

Antwort1

Preview.app dazu bringen, AppleScript-Befehle zu akzeptieren

Standardmäßig funktioniert AppleScripting Preview nicht, da Preview das erforderliche Wörterbuch fehlt. Um dies zu beheben, überprüfen SieLauris Antwort hier, wo die Einstellungen NSAppleScriptEnabledfür Preview.app erläutert werden.

Beenden Sie Preview.app, öffnen Sie dann ein Terminal und geben Sie ein:

sudo defaults write /Applications/Preview.app/Contents/Info NSAppleScriptEnabled -bool true
sudo chmod 644 /Applications/Preview.app/Contents/Info.plist
sudo codesign -f -s - /Applications/Preview.app


Schließen eines Fensters aus einer Anwendung

1) Nach Fensterindex oder Name des Fensters

Der Befehl zum Schließen eines Fensters einer beliebigen benannten Anwendung würde etwa so lauten:

tell application "Preview" to close window 1

… oder wenn Sie ein benanntes Dokumentfenster schließen möchten, zB foo.jpg:

sagen Sie der Anwendung "Vorschau", dass sie sich schließen soll (jedes Fenster, dessen Name "foo.jpg")

In Ihrem Shell-Skript würde das also lauten:

#!/bin/sh
osascript <<EOF
tell application "Preview"
  close (every window whose name is "$1")
end tell
EOF

Hier ist das erste an das Skript übergebene Argument der Name des Fensters, das Sie schließen möchten, z. B. ./quit.sh foo.jpg. Beachten Sie, dass Sie den Dateinamen in Anführungszeichen setzen müssen, wenn Ihre Datei Leerzeichen enthält, z. B. ./quit.sh "foo bar.jpg".

Oder wenn Sie beliebige Fenster einer beliebigen Anwendung schließen möchten, verwenden Sie Folgendes:

#!/bin/sh
osascript <<EOF
tell application "$1"
  close (every window whose name is "$2")
end tell
EOF

Hier würden Sie ./quit.sh Preview foo.jpgzum Beispiel verwenden.

2) Nach Dateinamen

Wenn Sie ein Fenster schließen möchten, das zu einem bestimmten Dokument gehört, aber den Dateinamen angeben möchten, benötigen Sie etwas anderes. Dies liegt daran, dass eine mehrseitige PDF-Datei als angezeigt werden könnte , Sie dies jedoch nur an das AppleScript foo.pdf (Page 1 of 42)übergeben möchten .foo.pdf

Hier durchlaufen wir die Fenster und vergleichen die Dateinamen mit dem an das Skript übergebenen Argument:

osascript <<EOF
tell application "Preview"
    set windowCount to number of windows
    repeat with x from 1 to windowCount
        set docName to (name of document of window x)
        if (docName is equal to "$1") then
            close window x
        end if
    end repeat
end tell
EOF

Jetzt können Sie einfach aufrufen ./quit.sh foo.pdf. Verallgemeinert für alle Apps mit benannten Dokumentfenstern wäre das:

osascript <<EOF
tell application "$1"
    set windowCount to number of windows
    repeat with x from 1 to windowCount
        set docName to (name of document of window x)
        if (docName is equal to "$2") then
            close window x
        end if
    end repeat
end tell
EOF


Vorbehalt: Automatisches Schließen von Preview.app

Preview.app ist eine dieser Anwendungen, die automatisch beendet wird, sobald das letzte Dokumentfenster geschlossen wird. Dies geschieht, um Speicher zu sparen und „aufzuräumen“. Um dieses Verhalten zu deaktivieren, führen Sie Folgendes aus:

defaults write -g NSDisableAutomaticTermination -bool TRUE

Um dies rückgängig zu machen, ändern Sie es natürlich TRUEzu FALSE.


Verwenden von Funktionen anstelle von Skripten

Abschließend empfehle ich, Ihre Skripte in eine Funktion zu packen, die in Ihrer Shell immer verfügbar ist. Fügen Sie dazu die Skripte zu Ihrer hinzu ~/.bash_profile. Erstellen Sie diese Datei, falls sie noch nicht vorhanden ist.

cw() {
osascript <<EOF
tell application "$1"
    set windowCount to number of windows
    repeat with x from 1 to windowCount
        set docName to (name of document of window x)
        if (docName is equal to "$2") then
            close window x
        end if
    end repeat
end tell
EOF
}

Sobald Sie Ihr Bash-Profil gespeichert und die Shell neu gestartet haben, können Sie cw Preview foo.pdfvon überall aus anrufen.

Antwort2

Die Antwort von slhck sieht gut und ausführlich aus.Achtung, Ausführung der dritten Codezeile:

sudo codesign -f -s - /Applications/Preview.app

„scheint“ dazu geführt zu haben, dass Preview bei jedem Start mit folgendem Ergebnis abstürzte:

Application Specific Information:
XPC domain creation failed: The code signature is not valid: The operation couldn’t be completed. (OSStatus error -67061.)

Laut dem Codesign-Handbuch -fbedeutet dies, dass „das Codezeichen eine vorhandene Signatur ersetzt“ und -s„der Code am angegebenen Pfad signiert wird“ … in diesem Fall-

Offenbar ist Preview jetzt falsch signiert und unbrauchbar. :(

verwandte Informationen