Почему этот яблочный скрипт не работает должным образом?

Я пишу сервис, используя Automotor. Он получает no input в any application.

Все, что он делает, это запускает этот простой скрипт:

on run {input, parameters}
--FIRST BLOCK
    tell application "System Events"
        set app_name to name of the first process whose frontmost is true
    end tell
--SECOND BLOCK
    if (do shell script "defaults read com.apple.finder AppleShowAllFiles") is equal to "0" then
        do shell script "defaults write com.apple.finder AppleShowAllFiles 1"
    else
        do shell script "defaults write com.apple.finder AppleShowAllFiles 0"
    end if
--THIRD BLOCK
    do shell script "killall Finder"
    delay 0.5
--FOURTH BLOCK
    if (app_name is equal to "Finder") then
        tell application "Finder"
            activate
        end tell
    end if
end run

Я проведу вас через это шаг за шагом:

первый блок: получить имя текущего переднего приложения и сохранить его в переменной app_name.

Второй блок: включение или выключение переменной скрытых файлов в зависимости от ее значения.

третий блок: запустите killall Finder, чтобы перезапустить Finder, включив переключатель из второго блока. Пауза 0.5 сек, как-то это необходимо (не знаю зачем, но без этого следующая инструкция будет проигнорирована).

Четвертый блок: проверьте, какой была переменная app_name. Если он равен Finder, это означает, что Finder был активен при запуске скрипта, поэтому активируйте Finder еще раз (killall Finder оставляет его в фоновом режиме).

Проблема. Все работает так, как ожидалось, но есть одно но: при использовании этой службы в Finder Finder больше не активируется.

Кто-то может возразить, что с кодом в четвертом блоке должно быть что-то не так, но я немного поэкспериментировал, чтобы показать, что все работает так, как ожидалось:

Когда я заменяю equal на not equal и запускаю скрипт из любого приложения, кроме Finder, Finder ДЕЙСТВИТЕЛЬНО активируется, как и должно быть.

Таким образом, кажется, что проблема возникает только тогда, когда скрипт запускается, когда Finder находится впереди.

(Вот что должна делать служба: из любого приложения переключать видимость скрытых файлов в Finder. Когда Finder был впереди, он должен быть впереди после выполнения скрипта, когда другое приложение было впереди, это приложение должен быть впереди.)

Я на Льве.


person romeovs    schedule 19.09.2011    source источник


Ответы (2)


На моей машине работает небольшая модификация скрипта @regulus6633:

-- restart the Finder
tell application "Finder" to launch      # always launch
if (app_name is equal to "Finder") then
  tell application "Finder" to activate  # activate separately
end if

Должен признаться, я не совсем уверен, почему и как — документация AppleScript для запустить и activate не подходят в случае с Finder…

person kopischke    schedule 20.10.2011

Я тоже сталкивался с этим раньше. По сути, вы говорите, что когда это запускается, когда Finder находится на самом переднем плане, Finder на самом деле не самый передний. И это правда, потому что вы сказали, что это сервис-автомат. Я считаю, что автоматизатор управляется приложением под названием «Automator Runner». Так что на самом деле, как только сервис запускается, Automator Runner становится самым передним. Обратите внимание, что это безликое приложение, поэтому вы не можете видеть, что оно самое переднее, но это так. Поэтому, когда вы проверяете, является ли Finder самым передним, это никогда не бывает. Имеет ли это смысл? Я вижу то же самое при запуске яблочных скриптов, потому что они запускаются с помощью Applescript Runner.

Итак, как это исправить? Вот мысль. Сделайте это своим ПЕРВЫМ БЛОКОМ и посмотрите, поможет ли это...

tell application "System Events"
    set app_name to name of the first process whose frontmost is true
    if app_name is "Automator Runner" then
        set visible of process "Automator Runner" to false
        set app_name to name of first process whose frontmost is true
    end if
end tell

ПРИМЕЧАНИЕ. Я не уверен, что Automator Runner будет самым передним процессом. Это может быть что-то еще, например, название вашего действия автомата. Но вы можете быть уверены, что что-то еще находится на переднем плане из-за выполняемого действия автомата... поэтому, если мой код не работает, вам просто нужно выяснить имя процесса, который выполняется, когда выполняется ваше действие автомата, и поставить это в код. Вы всегда можете поместить «диалоговое окно отображения» в свой код, чтобы показать вам имя самого переднего процесса.

Еще один совет. В общем, я не люблю использовать команду KILLALL, если вместо нее можно использовать команду QUIT. Программа Quit разработана для Mac и обеспечивает корректную остановку действий. Как назло, в Finder есть команда выхода. Попробуйте это для 3-го и 4-го блоков. Вы увидите, что если Finder был самым передним, то мы активируем его, что снова делает его самым передним, но если это не так, мы запускаем его, чтобы он, по крайней мере, снова работал, но не выходил на передний план.

-- quit the Finder
tell application "Finder" to quit

-- delay until the Finder quits
repeat
    try
        tell application "System Events" to get first process whose name is "Finder"
        delay 0.1
    on error
        exit repeat
    end try
end repeat

-- restart the Finder
if (app_name is equal to "Finder") then
    tell application "Finder" to activate
else
    tell application "Finder" to launch
end if

EDIT: Кажется, ваш шаг № 2 неверен. Вам нужно использовать «ON» или «OFF» вместо 0 или 1. Попробуйте это...

if (do shell script "defaults read com.apple.finder AppleShowAllFiles") is equal to "ON" then
    do shell script "defaults write com.apple.finder AppleShowAllFiles OFF"
else
    do shell script "defaults write com.apple.finder AppleShowAllFiles ON"
end if
person regulus6633    schedule 19.09.2011
comment
это тоже не работает для меня. Я могу подтвердить, что переменная app_name действительно содержит Finder, используя диалоговые окна, но это все еще не работает. - person romeovs; 20.09.2011
comment
Я добавил раздел EDIT в свой пост. Вы устанавливаете значение plist на 0 или 1. Вам нужно использовать ON или OFF. - person regulus6633; 21.09.2011
comment
Материал из шага № 2 работает просто отлично. Я не понимаю, как это может повлиять на загрузку искателя или нет. Насколько мне известно, ON и OFF эквивалентны 1 и 0 во всех смыслах. - person romeovs; 21.09.2011
comment
Я запускаю это из applescript, а не из действия автомата. Итак, из applescript 1) Finder выходит на передний план, поэтому я не вижу вашей проблемы, и 2) 0 и 1 ничего для меня не делают. Я должен использовать ON или OFF. Кажется, я больше ничем не могу вам помочь, так что удачи в поиске вашей проблемы. - person regulus6633; 21.09.2011