Considérez le AppleScript suivant:
on is_running(appName)
tell application "System Events" to (name of processes) contains appName
end is_running
set safRunning to is_running("Safari")
if safRunning then
tell application "Safari"
-- Stuff I only want executed if Safari is running goes here.
end tell
return "Running"
else
return "Not running"
end if
Le problème: lorsque j'exécute cette opération via l'utilitaire de ligne de commande osascript
, si Safari n'est pas en cours d'exécution, il est lancé et le script signale «En cours d'exécution». Ce n'est pas le comportement que je désire ou auquel je m'attendrais. Notez que cela fonctionne comme souhaité/attendu lorsqu’il est exécuté dans l’éditeur AppleScript.
S'agit-il d'un bogue osascript
/d'un problème connu? Ou est-ce en quelque sorte le comportement voulu pour les raisons qui me manquent? Quelqu'un peut-il le faire fonctionner comme souhaité? (BTW, je suis sous OSX 10.7.5; je ne vois pas comment obtenir osascript
pour signaler un numéro de version).
Si vous commentez les lignes tell
/end tell
, elles se comporteront comme je le pensais: si Safari n'est pas en cours d'exécution, il ne le lancera pas et affichera "Pas en cours d'exécution". Donc il me sembleque la tell
me semble être à l’origine du lancement de Safari, mais elle n’a pas besoin d’être exécutée, elle est simplement présente dans le script ...? Pendant un moment, je me suis demandé si c'était peut-être juste comment tell
est supposé fonctionner, mais étant donné que ne fonctionne pasde cette façon dans l'éditeur AppleScript, je suppose que non ...
En fait, voici une autre version, madder, avec un comportement similaire:
on is_running(appName)
tell application "System Events" to (name of processes) contains appName
end is_running
set safRunning to is_running("Safari")
return safRunning
if false then
tell application "Safari"
end tell
end if
Cela lance toujours toujours Safari, même si tell
se trouve à l'intérieur d'un bloc if false
après l'instruction de retour! (Mais encore une fois, c'est bien dans l'éditeur AppleScript.)
BTW, ce comportement n'est pas limité à Safari, mais il n'est pas non plus universel:
Alors, est-ce que quelqu'un a une idée sur la façon dont je pourrais résoudre ce problème? Est-ce un bogue osascript
? Ou est-ce que je manque quelque chose à propos de la sémantique d'AppleScript?
Pour le contexte: j'essaie d'écrire un script (à intégrer/appelé à partir d'un python) qui interroge les navigateurs ouverts sur les URL des onglets qu'ils ont ouverts; Tout fonctionne très bien saufqui lance toujours Safari, qu'il soit ouvert ou non. J'ai résumé ce comportement indésirable au simple cas de test présenté ci-dessus. Je ne connais aucun moyen de Exécutez ce script à partir de python sans utiliser osascript
, à l'exception de appscript , que je ne souhaite pas utiliser car il n'est plus développé/pris en charge/recommandé .
Merci beaucoup pour toutes les contributions/idées!
Je suppose que la raison en est que chaque fois que vous appelez le script à partir de la ligne de commande avec osascript, le script est en cours de compilation.
Le fait de compiler sur une application tell aura toujours le lancement de l’application.
L'appel du script à partir de la ligne de commande avec osascript à partir d'un fichier pré-compilé, c'est-à-dire . scpt ne provoque pas ce problème, car il n'y a pas de compilation à effectuer.
Mais l'appeler à partir d'un fichier texte brut (.txt, .sh) permettra à l'application de se lancer.
Si vous ne voulez pas utiliser un fichier .scpt et un fichier texte brut, vous pouvez essayer l'astuce consistant à mettre une commande run script dans le script AppleScript.
on is_running(appName)
tell application "System Events" to (name of processes) contains appName
end is_running
set safRunning to is_running("Safari")
if safRunning then
run script "tell application \"Safari\"
open location \"http://google.com\"
end tell"
return "Running"
else
return "Not running"
end if
Le script dans exécuter le script est uniquement compilé en cas de besoin. Vous devrez échapper aux caractères tels que les guillemets, comme dans mon exemple.
Ce sera plus facile si vous écrivez d'abord le script dans un document normal AppleScript et le compilez pour vérifier les erreurs.
Puis copiez-le dans le fichier texte brut.
METTRE À JOUR **
La méthode que j'ai utilisée ci-dessus est issue d'un vieux script que j'avais utilisé pour résoudre ce problème un certain temps avant de répondre ici.
La réponse fonctionne et n'essaie pas d'être élégante. ;-)
J'aime réellement user1804762 méthode ci-dessous. Comme cela fonctionne, mais que la réponse n’est pas assez claire, je vais vous donner un exemple d’utilisation.
set appName to "Safari"
if application appName is running then
tell application id (id of application appName)
open location "http://google.com"
end tell
return "Running"
else
return "Not running"
end if
Ce script peut être exécuté à partir de la ligne de commande avec osascript
exemple:
osascript /Users/USERNAME/Desktop/foo.scpt
Notez que le script est enregistré en tant que script compilé. Cela fonctionnera bien et vous pourrez également l'enregistrer et l'utiliser en tant que script en texte brut.
c'est à dire.
osascript /Users/USERNAME/Desktop/foo.applescript
Quelques infos:
"Modèle objet d'application amélioré":
tell application "iTunes"
if it is running then
pause
end if
end tell
Vous pouvez aussi le faire de cette façon:
if application "iTunes" is running then
tell application "iTunes" to quit
end if
Vous pouvez aussi faire ceci:
get name of application "iTunes"
get version of application "iTunes"
Et pour compléter le voyage:
get id of application "TextEdit" --> "com.Apple.TextEdit"
tell application id "com.Apple.TextEdit"
make new document
end tell
C'était le "modèle objet d'application amélioré". Si une application est toujours lancée (par exemple, la première fois que vous compilez et exécutez le script), je suppose que c'est parce qu'AS doit obtenir des informations de l'application qu'elle n'a pas trouvées dans le dictionnaire (ou quelque chose comme ça ...? ).
OK, je sais que cette question est vraiment ancienne, mais je suis tombé sur cette question à la recherche d’un problème différent et j’ai dû réfléchir à la complexité de certaines de ces réponses.
Le code simple pour réaliser ce que vous voulez (ed) est:
tell application "System Events"
if application process "Safari" exists then
-- do stuff you want to do only if Safari exists
end if
end tell
Sur les systèmes plus anciens, la syntaxe utilisée doit être:
tell application "System Events"
if exists of application process "Safari" is true then
-- do stuff you want to do only if Safari exists
end if
end tell
Un de ceux-ci devrait certainement fonctionner pour vous, chercheur intrépide de solutions Applescript pour l'action uniquement lorsqu'une application est en cours d'exécution.
Oh! Astuce bonus: Et si vous n'êtes pas sûr du nom exact du processus de l'application (c'est habituellement mais pas toujours le nom de l'application), avant de coder le script final exécuté
tell application "System Events"
get every application process
end tell
Et trouvez le nom du processus de votre application dans les résultats.
Voici une capture d'écran de l'exécution de cette commande. (Notez les zillions d'instances Google Chrome Helper. Merci Google!)
HTH!
Toutes les réponses précédemment faites souffrent du même problème, cependant:
Ils recherchent l'application par son nom. Toutefois, l'utilisateur peut renommer l'application. Le script croit alors que l'application ne s'exécute pas, alors qu'elle le fait.
Pour vérifier correctement qu'une application est en cours d'exécution, vous devez la trouver à l'aide de son ID d'ensemble, que l'utilisateur ne peut pas modifier.
L'ID de paquet peut être demandé avec cette commande, par exemple:
tell application "System Events"
get bundle identifier of application process "Safari"
end tell
Pour vérifier si une application avec un ID de bundle particulier est en cours d'exécution, utilisez ce code:
tell application "System Events"
set ids to bundle identifier of every application process
if ids contains "com.Apple.safari" then
return "Running"
else
return "Not running"
end if
end tell
En outre, voici un exemple pour vérifier si une application est en cours d'exécution, puis la quitter, puis la relancer, en veillant à ce que la même application soit exécutée auparavant, et qu'aucune autre copie ne soit présente:
set bundleID to "com.Apple.safari"
set apps to runningApps(bundleID)
set appCount to length of apps
if appCount is not 0 then
quit application id bundleID
repeat while length of runningApps(bundleID) = appCount
-- wait for the app to quit
end repeat
open first item of apps
end if
on runningApps(bundleID)
-- The try block is to catch the rare case of having more than one
-- copy of an app running at the same time. Unfortunately, in that
-- case this code will not run as expected, because we don't get the
-- correct list of multiple items back then. But at least the script
-- will not crash from it but handle it gracefully.
tell application "System Events"
try
return application file of (every application process whose bundle identifier = bundleID)
end try
end tell
return {}
end runningApps
tell application "Finder"
set applicationsnames to get the name of every process whose visible is true
end tell
set appName to "Safari"
if applicationsnames does not contain appName then
say (appName & " is not running")
--add here what you want to happen
end if
return applicationsnames
Ceci retourne {"Finder", "JavaAppLauncher", "firefox", "Microsoft Word", "iTunes", "AppleScript Editor"}
pour moi
J'espère que cela t'aides
J'ai eu le même problème que décrit ici en essayant de configurer un AppleScript (déclenché par un geste BetterTouchTool) qui lit/met en pause VLC ou iTunes, mais seulement iTunes si VLC n'est pas en cours d'exécution (à cause de mon flux de travail) et, bien entendu, uniquement VLC c'est en cours d'exécution. (J'utilise le déclencheur automatique de pause/lecture pour iTunes dans les paramètres de VLC, pour le lancement et la fermeture de l'application.)
VLC a toujours été lancé lors de la première utilisation du BetterTouchTool-trigger après chaque relance de BTT, car le cache du dictionnaire est supprimé à ce moment-là et le gestionnaire AppleScript doit lancer chaque application scriptée si un tell le vise pour pouvoir l'appeler. dictionnaire.
Je n'ai rien trouvé qui évite cela nulle part; il y a eu quelques tentatives, mais aucune n'a fonctionné pour moi car l'appel du dictionnaire par le gestionnaire de script ne peut en aucun cas être influencé. Je suis venu avec cette solution de contournement sale:
Cela conduira à la première compilation du script n'appelant pas l'application (VLC, dans mon cas) directement, mais uniquement le script, ce qui signifie que l'application n'aura pas besoin de se lancer.
VLC devra être lancé une fois ce fichier séparé appelé, mais si vous appelez ce fichier pour indiquer quelque chose à VLC, vous aurez VLC déjà ouvert (ou vous voudrez l'ouvrir).
Le script AppleScript que j'appelle via mon BetterTouchTool-trigger (un tap spécifique sur le trackpad, dans mon cas) ressemble à ceci:
if application "iTunes" is running and not application "VLC" is running then
tell application "iTunes" to playpause
se termine si si l'application "VLC" est en cours d'exécution, alors exécuter le script "/Users/jannis/bin/PlayVLC.scpt"end if
Le fichier AppleScript séparé ("PLayVLC.scpt, enregistré dans un dossier appelé" bin "dans mon dossier utilisateur que j'ai créé manuellement il y a bien longtemps à de telles fins) est le suivant:
tell application "VLC" to play
Si vous ouvrez ce script manuellement, il lancera bien sûr également VLC. Espérons que cela ne sera pas nécessaire souvent, ni jamais.
En fait, je ne sais vraiment pas si cela crée des problèmes plus profonds que je ne connais pas car je ne suis pas un codeur professionnel; Si oui, s'il vous plaît informez-moi. J'espère que cela aide n'importe qui!