Comment fermer une fenêtre à partir d'une application, en passant le nom de fichier?

9

J'essaie de produire une commande shell basée sur Applescript qui indique à l'application Aperçu de Mac OS X de fermer une fenêtre particulière.

#!/bin/sh

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

Mais cela ne fonctionne pas: je reçois le message d'erreur

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

Question connexe: comment fermer une application OS X à partir de la ligne de commande à l'aide d'un alias défini dans mon .bash_profile?

Ewan Delanoy
la source
Cela devrait fonctionner comme prévu. Comment appelez-vous votre script exactement? Remarque: Votre script ne fermera pas une fenêtre particulière. Il quittera l'application, fermant ainsi toutes les fenêtres de document que l'application pourrait avoir ouvertes. Pour fermer un document particulier, l'application a ouvert mais ne quitte pas l'application en soi, vous avez besoin d'un script différent. Bien que la plupart des applications se ferment lorsque leur dernière fenêtre de document est fermée, toutes ne le font pas - cela dépend également de la version d'OS X que vous utilisez.
slhck
@slhck: "fermer un document particulier que l'application a ouvert mais ne pas quitter l'application en soi" est exactement ce dont j'ai besoin. Connaissez-vous un endroit où un tel "script différent" est expliqué?
Ewan Delanoy

Réponses:

10

Obtenir Preview.app pour accepter les commandes AppleScript

Par défaut, AppleScripting Preview ne fonctionnera pas car il manque le dictionnaire nécessaire à Preview. Pour résoudre ce problème, consultez la réponse de Lauri ici , ce qui explique le réglage NSAppleScriptEnabledde Preview.app.

Quittez Preview.app, puis ouvrez un terminal et entrez:

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


Fermer une fenêtre à partir d'une application

1) Par index de fenêtre ou nom de la fenêtre

La commande pour fermer une fenêtre d'une application nommée ressemblerait à ceci:

tell application "Preview" to close window 1

… Ou si vous souhaitez fermer une fenêtre de document nommée, par exemple foo.jpg:

dire à l'application "Aperçu" de se fermer (chaque fenêtre dont le nom est " foo.jpg ")

Donc, dans votre script shell, ce serait:

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

Ici, le premier argument transmis au script est le nom de la fenêtre que vous souhaitez fermer, par exemple ./quit.sh foo.jpg. Notez que si votre fichier contient des espaces, vous devez citer le nom du fichier, par exemple ./quit.sh "foo bar.jpg".

Ou si vous souhaitez fermer des fenêtres arbitraires à partir de n'importe quelle application, utilisez ceci:

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

Ici, vous utiliseriez ./quit.sh Preview foo.jpgpar exemple.

2) Par nom de fichier

Si vous souhaitez fermer une fenêtre qui appartient à un certain document, mais en fournissant le nom du fichier, vous avez besoin d'autre chose. Cela est dû au fait qu'un fichier PDF de plusieurs pages peut s'afficher en tant que foo.pdf (Page 1 of 42), mais vous souhaitez simplement passer foo.pdfau AppleScript.

Ici, nous parcourons les fenêtres et comparons les noms de fichiers avec l'argument passé au script:

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

Maintenant, vous pouvez simplement appeler ./quit.sh foo.pdf. De manière généralisée, pour toutes les applications avec des fenêtres de document nommées, ce serait:

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


Mise en garde: Aperçu à fermeture automatique.app

Preview.app est l'une de ces applications qui se ferme automatiquement une fois sa dernière fenêtre de document fermée. Il le fait pour économiser de la mémoire et "nettoyer". Pour désactiver ce comportement, exécutez ce qui suit:

defaults write -g NSDisableAutomaticTermination -bool TRUE

Bien sûr, pour annuler cela, passez TRUEà FALSE.


Utiliser des fonctions au lieu de scripts

Enfin, je vous suggère de mettre vos scripts dans une fonction qui est toujours disponible dans votre shell. Pour ce faire, ajoutez les scripts à votre ~/.bash_profile. Créez ce fichier s'il n'existe pas.

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
}

Une fois que vous avez enregistré votre profil bash et redémarré le shell, vous pouvez appeler cw Preview foo.pdfde partout.

slhck
la source
J'ai essayé ça. Cette fois, je ne reçois aucun message d'erreur, mais le script ne fonctionne toujours pas: la fenêtre reste visible à l'écran.
Ewan Delanoy
Ça a marché pour moi. Si vous ouvrez un document dans Preview.app, puis ouvrez l'éditeur AppleScript et entrez tell application "Preview" to windows, cela vous donne-t-il des résultats? Quel script utilisez-vous exactement?
slhck
Je n'utilise pas l'éditeur AppleScript, j'utilise uniquement du "code applescript intégré" dans un script bash, comme expliqué dans l'OP, stocké dans un fichier .sh.
Ewan Delanoy
En fait, je suis généralement très satisfait des scripts shell et c'est mon premier script Apple. Je viens de faire ce que vous avez conseillé dans votre dernier commentaire, et j'ai obtenu: "{id fenêtre 113 de l'application" Aperçu "}" comme réponse. C'est ce que je devrais obtenir?
Ewan Delanoy
De plus, lorsque je compile << dis à l'application "Preview" de fermer "musixdoc.pdf" >> avec l'éditeur applescript, cela ne fonctionne pas non plus: la fenêtre musixdoc.pdf reste visible à l'écran.
Ewan Delanoy
0

La réponse de slhck semble bonne et approfondie. Attention, exécutez la troisième ligne de code :

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

'semble' avoir provoqué le plantage de Preview à chaque lancement avec les éléments suivants:

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

Selon le manuel de codesign, cela -foblige «le code à remplacer et la signature existante» et -s«à signer le code au chemin indiqué»… dans ce cas-

Apparemment, l'aperçu est désormais incorrectement signé et inutilisable. :(

David C
la source