¿Cómo cierro una ventana desde una aplicación, pasando el nombre del archivo?

9

Estoy tratando de producir un comando de shell basado en Applescript que le dice a la aplicación Vista previa de Mac OS X que cierre una ventana en particular.

#!/bin/sh

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

Pero esto no funciona: recibo el mensaje de error

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

Pregunta relacionada: ¿Cómo cierro una aplicación OS X desde la línea de comandos usando un alias definido en mi .bash_profile?

Ewan Delanoy
fuente
Esto debería funcionar como se esperaba. ¿Cómo estás llamando exactamente a tu guión? Nota: Su secuencia de comandos no cerrará una ventana en particular. Saldrá de la aplicación, cerrando así todas las ventanas de documentos que la aplicación podría haber abierto. Para cerrar un documento en particular, la aplicación se abrió pero no salió de la aplicación per se, necesita un script diferente. Si bien la mayoría de las aplicaciones se cierran cuando se cierra su última ventana de documento, no todas lo hacen; esto también depende de la versión de OS X que esté utilizando.
slhck el
@slhck: "cerrar un documento en particular que la aplicación ha abierto pero no salir de la aplicación per se" es exactamente lo que necesito. ¿Conoces algún lugar donde se explica un "guión diferente"?
Ewan Delanoy

Respuestas:

10

Obteniendo Preview.app para aceptar comandos AppleScript

De forma predeterminada, AppleScripting Preview no funcionará porque a Preview le falta el diccionario necesario. Para solucionar esto, verifique la respuesta de Lauri aquí , que explica la configuración NSAppleScriptEnabledde Preview.app.

Salga de Preview.app, luego abra una terminal e ingrese:

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


Cerrar una ventana desde una aplicación

1) Por índice de ventana o nombre de la ventana

El comando para cerrar una ventana de cualquier aplicación con nombre sería algo como esto:

tell application "Preview" to close window 1

... o si desea cerrar una ventana de documento con nombre, por ejemplo foo.jpg:

diga a la aplicación "Vista previa" que cierre (cada ventana cuyo nombre es " foo.jpg ")

Entonces, en su script de shell eso sería:

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

Aquí, el primer argumento pasado al script es el nombre de la ventana que desea cerrar, por ejemplo ./quit.sh foo.jpg. Tenga en cuenta que si su archivo contiene espacios, debe citar el nombre del archivo, por ejemplo ./quit.sh "foo bar.jpg".

O si desea cerrar ventanas arbitrarias desde cualquier aplicación, use esto:

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

Aquí, usarías ./quit.sh Preview foo.jpgpor ejemplo.

2) Por nombre de archivo

Si desea cerrar una ventana que pertenece a un documento determinado, pero que proporciona el nombre del archivo, necesita algo más. Esto se debe a que un PDF de varias páginas podría mostrarse como foo.pdf (Page 1 of 42), pero solo querría pasar foo.pdfal AppleScript.

Aquí iteramos a través de las ventanas y comparamos los nombres de los archivos con el argumento pasado al 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

Ahora puedes simplemente llamar ./quit.sh foo.pdf. De forma generalizada, para todas las aplicaciones con ventanas de documentos con nombre, eso sería:

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


Advertencia: cierre automático Preview.app

Preview.app es una de estas aplicaciones que se cierra automáticamente una vez que se cierra su última ventana de documento. Lo hace para ahorrar memoria y "limpiar". Para deshabilitar este comportamiento, ejecute lo siguiente:

defaults write -g NSDisableAutomaticTermination -bool TRUE

Por supuesto, para deshacer eso, cambie TRUEa FALSE.


Usar funciones en lugar de scripts

Finalmente, sugiero poner sus scripts en una función que siempre esté disponible en su shell. Para hacer esto, agregue los scripts a su ~/.bash_profile. Cree este archivo si no existe.

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
}

Una vez que guarde su perfil de bash y reinicie el shell, puede llamar cw Preview foo.pdfdesde cualquier lugar.

slhck
fuente
Intenté esto Esta vez no recibo ningún mensaje de error, pero el script aún no funciona: la ventana permanece visible en la pantalla.
Ewan Delanoy
Funcionó para mi. Si abre un documento en Preview.app, abra el Editor de AppleScript e ingrese tell application "Preview" to windows, ¿eso le da algún resultado? ¿Qué script exacto estás ejecutando?
slhck el
No uso el editor AppleScript, solo uso el "código AppleScript incrustado" en un script bash, como se explica en el OP, almacenado en un archivo .sh.
Ewan Delanoy
De hecho, generalmente estoy bastante contento con los scripts de shell y este es mi primer manuscrito. Acabo de hacer lo que me aconsejaste en tu último comentario y obtuve: "{window id 113 de la aplicación" Vista previa "}" como respuesta. ¿Es eso lo que debería obtener?
Ewan Delanoy
Además, cuando compilo << decirle a la aplicación "Vista previa" para cerrar "musixdoc.pdf" >> con el editor de AppleScript, tampoco funciona: la ventana musixdoc.pdf permanece visible en la pantalla.
Ewan Delanoy
0

La respuesta de slhck se ve bien y completa. Cuidado, ejecutando la tercera línea de código :

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

'parece' haber causado que Vista previa se bloquee en cada lanzamiento con lo siguiente:

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

De acuerdo con el manual de codeign, eso -festá obligando a 'firmar el código para reemplazar y la firma existente' y -ses 'firmar el código en la ruta dada' ... en este caso-

Aparentemente, la vista previa ahora está firmada incorrectamente e inutilizable. :(

David C
fuente