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

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

Estoy intentando producir un comando de shell basado en Applescript que le indique 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: aparece 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 comando usando un alias definido en mi .bash_profile?

Respuesta1

Conseguir que Preview.app acepte comandos de AppleScript

De forma predeterminada, AppleScripting Preview no funcionará porque a Preview le falta el diccionario necesario. Para solucionar este problema, consulteLa 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:

decirle a la aplicación "Vista previa" que se cierre (todas las ventanas cuyo nombre sea "foo.jpg")

Entonces, en tu script de shell sería:

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

Aquí, el primer argumento que se pasa 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 determinado documento, pero 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ás pasar foo.pdfal AppleScript.

Aquí iteramos a través de las ventanas y comparamos los nombres de 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, 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: Preview.app de cierre automático

Preview.app es una de estas aplicaciones que se cierra automáticamente una vez que se cierra la ventana del último 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, sugeriría poner sus scripts en una función que siempre esté disponible en su shell. Para hacer esto, agregue los scripts a su archivo ~/.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, podrá llamar cw Preview foo.pdfdesde cualquier lugar.

Respuesta2

La respuesta de slhck parece buena y completa.Cuidado, ejecutando la tercera línea de código.:

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

"parece" haber provocado que la Vista previa se bloquee en cada inicio 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.)

Según el manual de diseño de código, eso -fes forzar la 'señal de código para reemplazar la firma existente' y es -s'firmar el código en la ruta dada'... en este caso-

Aparentemente, la Vista previa ahora está firmada incorrectamente y es inutilizable. :(

información relacionada