Як закрити вікно програми, передаючи ім'я файлу?


9

Я намагаюся створити команду оболонки на основі Applescript, яка повідомляє програмі Preview з Mac OS X закрити певне вікно.

#!/bin/sh

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

Але це не працює: я отримую повідомлення про помилку

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

Пов'язане запитання: Як закрити додаток OS X з командного рядка, використовуючи псевдонім, визначений у моєму .bash_profile?


Це має працювати як очікувалося. Як ви точно називаєте свій сценарій? Примітка: Ваш сценарій не закриє певне вікно. Він закриє програму, тим самим закривши всі вікна документів, які програма може мати відкриті. Щоб закрити конкретний документ, програма відкрилася, але не виходила із програми сама по собі, вам потрібен інший сценарій. Хоча більшість програм закривають, коли останнє вікно документа закрито, але це не все - це також залежить від версії ОС X, яку ви використовуєте.
slhck

@slhck: "я закриваю конкретний документ, який програма відкрила, але не виходила з програми", саме те, що мені потрібно. Чи трапляється вам десь знати, де пояснюється такий "інший сценарій"?
Еван Деланой

Відповіді:


10

Отримання Preview.app для прийняття команд AppleScript

За замовчуванням AppleScripting Preview не працюватиме, оскільки у попередньому перегляді відсутній необхідний словник. Щоб виправити це, перевірте відповідь Лаурі тут , де пояснюється налаштування NSAppleScriptEnabledдля Preview.app.

Закрийте Preview.app, потім відкрийте термінал і введіть:

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


Закриття вікна програми

1) За індексом вікна або назвою вікна

Команда закрити вікно будь-якої названої програми буде приблизно таким:

tell application "Preview" to close window 1

… Або якщо ви хочете закрити назване вікно документа, наприклад foo.jpg:

скажіть програмі "Попередній перегляд" закрити (кожне вікно, ім'я якого " foo.jpg ")

Отже, у вашому сценарії оболонки це:

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

Тут перший аргумент, переданий сценарію, - це ім'я вікна, яке ви хочете закрити, наприклад ./quit.sh foo.jpg. Зауважте, що якщо у вашому файлі є пробіли, ви повинні навести ім'я файлу, наприклад ./quit.sh "foo bar.jpg".

Або якщо ви хочете закрити довільні вікна з будь-якої програми, скористайтеся цим:

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

Тут ви б використали, ./quit.sh Preview foo.jpgнаприклад.

2) За назвою файлу

Якщо ви хочете закрити вікно, яке належить певному документу, але надає ім'я файлу, вам потрібно щось інше. Це тому, що багатосторінковий PDF може відображатися як foo.pdf (Page 1 of 42), але ви просто хочете перейти foo.pdfдо AppleScript.

Тут ми повторюємо вікна та порівнюємо назви файлів з аргументом, переданим сценарію:

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

Тепер ви можете просто зателефонувати ./quit.sh foo.pdf. Узагальнено для всіх програм із названими вікнами документів це:

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


Caveat: Автоматичне закриття Preview.app

Preview.app - одна з таких програм, яка автоматично закривається після закриття останнього вікна документа. Це робиться для того, щоб зберегти пам’ять і «очистити». Щоб відключити цю поведінку, виконайте наступне:

defaults write -g NSDisableAutomaticTermination -bool TRUE

Звичайно, щоб скасувати це, змініть TRUEна FALSE.


Використання функцій замість скриптів

Нарешті, я б запропонував ввести ваші сценарії у функцію, яка завжди доступна у вашій оболонці. Для цього додайте сценарії до свого ~/.bash_profile. Створіть цей файл, якщо його не існує.

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
}

Після того як ви збережете свій bash-профіль і перезапустите оболонку, ви можете зателефонувати cw Preview foo.pdfзвідусіль.


Я спробував це. Цього разу я не отримую повідомлення про помилку, але сценарій все ще не працює: вікно залишається видимим на екрані.
Еван Деланой

Це працювало для мене. Якщо ви відкриєте документ у Preview.app, потім відкрийте редактор AppleScript і введіть tell application "Preview" to windows, чи це дає результати? Який точний сценарій ти працюєш?
slhck

Я не використовую редактор AppleScript, я використовую лише "вбудований код яблучного коду" у скрипті bash, як пояснено в ОП, який зберігається у файлі .sh.
Еван Деланой

Насправді я зазвичай дуже задоволений сценаріями оболонки, і це мій перший апплептик. Я просто зробив те, що ви порадили у своєму останньому коментарі, і отримав: "{window id 113 програми" Попередній перегляд "}" як відповідь. Це те, що я повинен отримати?
Еван Деланой

Крім того, коли я компілюю програму << Tell "Попередній перегляд", щоб закрити "musixdoc.pdf" >> редактором applescript, це також не працює: вікно musixdoc.pdf залишається видимим на екрані.
Еван Деланой

0

Відповідь slhck виглядає добре і ретельно. Остерігайтеся, виконуючи третій рядок коду :

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

"Здається" спричинило збій програми Preview при кожному запуску із наступним:

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

Згідно з посібником з -fкодового дизайну, це змушує "кодовий знак замінювати і існуючий підпис", а також -s"підписувати код у вказаному шляху" ... в цьому випадку-

Мабуть, попередній перегляд зараз неправильно підписаний і непридатний. :(

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.