Wie schließe ich ein Fenster aus einer Anwendung, indem ich den Dateinamen übergebe?

9

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

#!/bin/sh

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

Das funktioniert aber nicht: Ich bekomme 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 mit einem in meinem .bash_profile definierten Alias?

Ewan Delanoy
quelle
Dies sollte wie erwartet funktionieren. Wie rufen Sie Ihr Skript genau auf? Hinweis: Ihr Skript schließt ein bestimmtes Fenster nicht. Die Anwendung wird beendet, wodurch alle Dokumentfenster geschlossen werden, die die Anwendung möglicherweise geöffnet hat. Um ein bestimmtes Dokument zu schließen, das die Anwendung geöffnet hat, die Anwendung jedoch nicht per se beendet, benötigen Sie ein anderes Skript. Während die meisten Anwendungen beendet werden, wenn ihr letztes Dokumentfenster geschlossen wird, tun dies nicht alle - dies hängt auch von der Version von OS X ab, die Sie verwenden.
Slhck
@slhck: "Schließen Sie ein bestimmtes Dokument, das die Anwendung geöffnet hat, aber beenden Sie die Anwendung nicht per se" ist genau das, was ich brauche. Kennen Sie zufällig einen Ort, an dem ein solches "anderes Skript" erklärt wird?
Ewan Delanoy

Antworten:

10

Preview.app dazu bringen, AppleScript-Befehle zu akzeptieren

Standardmäßig funktioniert die AppleScripting-Vorschau nicht, da in der Vorschau das erforderliche Wörterbuch fehlt. Um dies zu beheben, überprüfen Sie Lauris Antwort hier , in der die Einstellung NSAppleScriptEnabledfür Preview.app erläutert wird .

Beenden Sie Preview.app, öffnen Sie ein Terminal und geben Sie Folgendes 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 benannten Anwendung lautet ungefähr so:

tell application "Preview" to close window 1

… Oder wenn Sie ein benanntes Dokumentfenster schließen möchten, z foo.jpg.

Weisen Sie die Anwendung an, "Vorschau" zu schließen (jedes Fenster mit dem Namen " foo.jpg ").

In Ihrem Shell-Skript wäre das also:

#!/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 ./quit.sh foo.jpg. Beachten Sie, dass Sie, wenn Ihre Datei Leerzeichen enthält, den Dateinamen angeben müssen, z ./quit.sh "foo bar.jpg".

Oder wenn Sie beliebige Fenster aus einer 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 Dateiname

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

Hier iterieren wir durch 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 anrufen ./quit.sh foo.pdf. Allgemein gilt für alle Apps mit benannten Dokumentfenstern Folgendes:

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


Vorsichtsmaßnahme: Automatisch schließende Preview.app

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

defaults write -g NSDisableAutomaticTermination -bool TRUE

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


Verwenden von Funktionen anstelle von Skripten

Schließlich würde ich vorschlagen, Ihre Skripte in eine Funktion einzufügen, die immer in Ihrer Shell verfügbar ist. Fügen Sie dazu die Skripte zu Ihrem hinzu ~/.bash_profile. Erstellen Sie diese Datei, wenn sie 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 .

slhck
quelle
Ich habe es versucht. Diesmal erhalte ich keine Fehlermeldung, aber das Skript funktioniert immer noch nicht: Das Fenster bleibt auf dem Bildschirm sichtbar.
Ewan Delanoy
Es hat bei mir funktioniert. Wenn Sie ein Dokument in Preview.app öffnen, dann den AppleScript-Editor öffnen und eingeben tell application "Preview" to windows, erhalten Sie dann Ergebnisse? Welches genaue Skript führen Sie aus?
Slhck
Ich verwende nicht den AppleScript-Editor, sondern nur "eingebetteten Applescript-Code" in einem Bash-Skript, wie im OP erläutert, das in einer .sh-Datei gespeichert ist.
Ewan Delanoy
Tatsächlich bin ich normalerweise ziemlich zufrieden mit Shell-Skripten und dies ist mein erstes Applescript. Ich habe gerade getan, was Sie in Ihrem letzten Kommentar empfohlen haben, und als Antwort: "{Fenster-ID 113 der Anwendung" Vorschau "}" erhalten. Soll ich das bekommen?
Ewan Delanoy
Wenn ich << der Anwendung "Vorschau" kompiliere, um "musixdoc.pdf" >> mit dem Applescript-Editor zu schließen, funktioniert dies ebenfalls nicht: Das Fenster musixdoc.pdf bleibt auf dem Bildschirm sichtbar.
Ewan Delanoy
0

Die Antwort von slhck sieht gut und gründlich aus. Vorsicht, Ausführung der dritten Codezeile :

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

'scheint' dazu geführt zu haben, dass Preview bei jedem Start wie folgt abstürzt:

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

Laut dem Handbuch für Codesigns bedeutet dies, dass das Codezeichen -fersetzt und die vorhandene Signatur ersetzt werden muss und dass -sder Code auf dem angegebenen Pfad signiert werden muss. In diesem Fall-

Anscheinend ist die Vorschau jetzt falsch signiert und unbrauchbar. :(

David C.
quelle