Como eu fecho uma janela de um aplicativo, passando o nome do arquivo?

9

Estou tentando produzir um comando shell baseado em Applescript que informe ao aplicativo Preview do Mac OS X para fechar uma janela específica.

#!/bin/sh

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

Mas isso não funciona: recebo a mensagem de erro

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

Pergunta relacionada: Como faço para fechar um aplicativo do OS X a partir da linha de comando usando um alias definido no meu .bash_profile?

    
por Ewan Delanoy 01.01.2013 / 10:55

2 respostas

9

Obtendo o Preview.app para aceitar comandos do AppleScript

Por padrão, o AppleScripting Preview não funciona porque o Preview não possui o dicionário necessário. Para corrigir isso, verifique a resposta de Lauri aqui , que explica a configuração de NSAppleScriptEnabled para Preview.app.

Saia do Preview.app, abra um terminal e digite:

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


Fechando uma janela de um aplicativo

1) Por índice de janela ou nome da janela

O comando para fechar uma janela de qualquer aplicativo nomeado seria algo assim:

tell application "Preview" to close window 1

... ou se você quiser fechar uma janela de documento nomeada, por exemplo foo.jpg :

tell application "Preview" to close (every window whose name is "foo.jpg")

Então, no seu script de shell, seria:

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

Aqui, o primeiro argumento passado para o script é o nome da janela que você deseja fechar, por exemplo, %código%. Observe que, se seu arquivo contiver espaços, você deverá citar o nome do arquivo, por exemplo, ./quit.sh foo.jpg .

Ou se você quiser fechar janelas arbitrárias de qualquer aplicativo, use:

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

Aqui, você usaria ./quit.sh "foo bar.jpg" , por exemplo.

2) Por nome de arquivo

Se você quiser fechar uma janela que pertença a um determinado documento, mas fornecendo o nome do arquivo, precisará de algo mais. Isso ocorre porque um PDF de várias páginas pode ser exibido como ./quit.sh Preview foo.jpg , mas você só quer passar foo.pdf (Page 1 of 42) para o AppleScript.

Aqui, iteramos pelas janelas e comparamos os nomes dos arquivos com o argumento passado para o 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

Agora você pode simplesmente chamar foo.pdf . De forma generalizada, para todos os aplicativos com janelas de documentos nomeados, seria:

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


Advertência: Auto-fechamento Preview.app

Preview.app é um desses aplicativos que é encerrado automaticamente quando sua última janela do documento é fechada. Ele faz isso para economizar memória e "limpar". Para desabilitar esse comportamento, execute o seguinte:

defaults write -g NSDisableAutomaticTermination -bool TRUE

Claro, para desfazer isso, altere ./quit.sh foo.pdf para TRUE .


Usando funções em vez de scripts

Por fim, sugiro colocar seus scripts em uma função que esteja sempre disponível em seu shell. Para fazer isso, adicione os scripts ao seu FALSE . Crie este arquivo, se ele não existir.

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
}

Depois de salvar seu perfil bash e reiniciar o shell, você pode chamar ~/.bash_profile de qualquer lugar.

    
por 01.01.2013 / 11:15
0

A resposta do slhck parece boa e completa. Cuidado, executando a terceira linha de código :

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

'parece' ter causado uma falha na pré-visualização em todos os lançamentos com o seguinte:

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

De acordo com o manual de codesign, que -f está forçando 'sinal de código a substituir e assinatura existente' e -s é 'assine o código no caminho dado'… neste caso -

Aparentemente, a Visualização está incorretamente assinada e inutilizada. : (

    
por 04.08.2014 / 00:34