Lo script del servizio di automazione avvia SEMPRE l'applicazione, ignorando le condizioni

3

Ho scritto un piccolo script di servizio per aprire una finestra terminale iTerm su una cartella arbitraria su Finder.

Voglio controllare se iTerm è in esecuzione e se deve aprire la sessione del terminale in una nuova scheda anziché su una esistente.

Lo script va in questo modo:

on run {input, parameters}

set cdPath to "cd " & (quoted form of POSIX path of (input as string))

if application "iTerm" is running then
    display notification "running"
    tell application "iTerm"
        set termWin to (current terminal)
        tell termWin
            launch session "Default"
            tell the last session
                write text cdPath
            end tell
        end tell
    end tell
else
    display notification "not running"
    tell application "iTerm"
        activate
        set termWin2 to (current terminal)
        tell termWin2
            tell the last session
                write text cdPath
            end tell
        end tell
    end tell
end if
return input
end run

Il problema è che quando eseguo lo script come servizio, si comporterà sempre come se iTerm fosse già in esecuzione (visualizzando la notifica "in esecuzione"), anche se iTerm è chiuso e NON funziona in modo molto chiaro.

Ma se incollo lo script nello Script Editor (impostando cdPath su un valore letterale, come set cdPath to "cd /etc" ) ed eseguirlo direttamente, funzionerà correttamente, aprendo una nuova istanza iTerm o riutilizzando uno esistente e creando un nuovo scheda e visualizza le notifiche corrispondenti.

Cosa sta succedendo qui? Perché eseguire lo script come servizio potrebbe rilevare l'applicazione come eseguita indipendentemente da cosa?

Aggiorna

Se semplifico lo script semplicemente visualizzando le notifiche in questo modo:

on run {input, parameters}

set cdPath to "cd " & (quoted form of POSIX path of (input as string))

  if application "iTerm" is running then
    display notification "running"
  else
    display notification "not running"
  end if
  return input
end run

Si comporterà come previsto (visualizzando "in esecuzione" o "non in esecuzione" di conseguenza).

Ma se aggiungo la parte "tell application", passerà sempre attraverso il ramo "running", a prescindere da cosa.

Ad es .:

on run {input, parameters}

set cdPath to "cd " & (quoted form of POSIX path of (input as string))

  if application "iTerm" is running then
    display notification "running"
  else
    display notification "not running"
    tell application "iTerm"
        activate
    end tell
  end if
  return input
end run

Aprirà sempre iTerm (anche se tell application "iTerm" è sul ramo "non in esecuzione", ma visualizza la notifica "in esecuzione", dal ramo "è in esecuzione" ... La semplice presenza di un "tell applicazione" attiverà l'apertura dell'app, quindi il servizio verrà eseguito.

C'è un modo per aggirare questo?

Grazie e saluti.

    
posta yivi 15.11.2015 - 10:52
fonte

3 risposte

1

Le restrizioni di sicurezza di El-Capitans NON sono responsabili di comportamenti errati sopra. Ho testato ancora una volta lo script e ho scoperto che:

  • Qualsiasi "è in esecuzione" -phrase deve avere un breve "ritardo" davanti per restituire in modo affidabile una risposta vera ... ma ancora non lo farà se viene chiamato come app servizio.
  • Inoltre, suppongo che gli script di Automator siano in qualche modo "pre-elaborati" prima di essere eseguiti come Servizi.
    Tutti gli if-branch sono valutati (riprodotti attraverso) e quindi attivati "just in case".

In codice jweaks a stack overflow , iTerm è influenzato solo direttamente nella seconda clausola ("tell ...").

tell application "System Events" to set theProcesses to name of every ¬
    every process whose visible is true

if theProcesses contains "iTerm" then display notification "running"
else [...]


Prova questo codice in ScriptEditor, Automator e come servizio in Safari:

display notification "" & running of application "TextEdit"
tell application "TextEdit" to activate
quit application "TextEdit"
display notification "" & running of application "TextEdit"

Otterrai risultati diversi da AppleScript / Automator (= > false + true ) e Safari ( true + true ). < br> Soprattutto il true di AppleScript / Automator della seconda notifica è abbastanza indicativo.

... tuttavia, se si inserisce solo un minuto di ritardo, ad esempio 0,01, dopo la riga "quit", l'esecuzione verrà verificata come "false" - se lo script viene eseguito da AppleScript / Automator.

    
risposta data 07.12.2015 - 17:29
fonte
0

A volte ho notato anche questo comportamento durante l'esecuzione di script, è strano. Sebbene la maggior parte delle volte ciò non avvenga quando non si esegue lo script tramite Script Editor. Tuttavia, ecco un'alternativa migliore:

tell application "System Events"
    # Adding tell application block has no effect on the if condition
    # Try it with TextEdit, that's what I using to try this code, and works fine.
    if (the name of application processes as text) contains "iTerm" then
        # Will quit the application if running
        log "Running"
        tell application "iTerm" to quit
    else
        # Will launch the application otherwise.
        log "Not Running"
        tell application "iTerm" to activate
    end if
end tell
    
risposta data 15.11.2015 - 17:53
fonte
0

Ho appena trovato un modo per farlo. Anche se sto creando un'applicazione invece di un servizio, sono quasi la stessa cosa. L'idea di base è di mettere tell application iTerm in un altro script o in virgolette, in modo tale che il processo di ottimizzazione non lo renda aperto prima di eseguire questo script. Così otterrai il risultato reale di if application "iTerm" is running .

Ma nello script citato, poiché c'è tell application part, sappiamo già che iTerm sarà aperto prima di tutto, possiamo direttamente activate iTerm e usare current session of current terminal (infatti, anche in Automator, questo ancora funziona anche se iTerm non viene aperto prima). Non sono sicuro che delay 0.01 sia necessario qui (puoi provare sul tuo computer). Ma questo funziona per il mio scopo, ovvero aprire il percorso corrente del Finder in una nuova finestra di iTerm nel desktop corrente. E se iTerm non è in esecuzione, non aprirà due finestre iTerm.

Fammi sapere cosa ne pensi. : -)

on run {input, parameters}
    tell application "Finder"
        set dir_path to quoted form of (POSIX path of (folder of the front window as alias))
    end tell
    CD_to(dir_path)
end run

on CD_to(theDir)
    if application "iTerm" is running then
        #display dialog "Running" # for debug
        run script "
            on run {q}
                tell application \":Applications:iTerm.app\"
                    set term to (make new terminal) # make a new window in current desktop since I don't want to mess with current ones
                    tell term
                        launch session \"Default\"
                        set sesh to current session
                    end tell
                    tell sesh
                        write text \"cd \" & q & \";clear;\"
                    end tell
                    activate
                end tell
            end run
        " with parameters {theDir}
    else
        #display dialog "Not Running" # for debug
        run script "
            on run {q}
                tell application \":Applications:iTerm.app\"
                    delay 0.01
                    activate
                    set sesh to current session of current terminal
                    tell sesh
                        write text \"cd \" & q & \";clear;\"
                    end tell
                end tell
            end run
        " with parameters {theDir}
    end if
end CD_to
# part of code comes from http://peterdowns.com/posts/open-iterm-finder-service.html
    
risposta data 27.05.2016 - 00:21
fonte

Leggi altre domande sui tag