Почему этот яблочный скрипт не работает должным образом? - PullRequest
2 голосов
/ 19 сентября 2011

Я пишу сервис, используя автомат.Он получает 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 был впереди, он должен быть впереди после выполнения извлечения, когда другое приложение было впереди, это приложение все еще должно быть впереди.)

Я на Lион.

Ответы [ 2 ]

1 голос
/ 20 сентября 2011

Я тоже сталкивался с этим раньше. По сути, вы говорите, что когда он запускается, когда Finder находится впереди, Finder на самом деле не впереди. И это правда, потому что вы сказали, что это услуга автоматизатора. Я считаю, что вещи автоматизатора управляются приложением под названием "Бегунок Automator". Таким образом, на самом деле, как только сервис запускается, Automator Runner становится первым. Обратите внимание, что это безликое приложение, поэтому вы не можете видеть, что оно самое переднее, но оно есть. Таким образом, когда вы проверяете, находится ли Finder впереди, это никогда не происходит. Имеет ли это смысл? Я вижу то же самое при запуске applecripts, потому что они запускаются с помощью 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 будет самым передовым процессом. Это может быть что-то еще, например, имя вашего действия автоматизатора. Но вы можете быть уверены, что что-то еще стоит впереди из-за запуска действия automator ... так что, если мой код не работает, вам просто нужно выяснить имя процесса, который выполняется, когда выполняется действие automator, и поместить это в код. Вы всегда можете вставить «диалог отображения» в свой код, чтобы показать вам имя самого переднего процесса.

Еще один совет. В общем, я не люблю использовать команду 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

РЕДАКТИРОВАТЬ: Кажется, ваш шаг № 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
0 голосов
/ 21 октября 2011

Небольшая модификация скрипта @ 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 для команд launch и activit не подходит для Finder ...

...