I’ve been banging away at a simple script that checks two different apps to see if they’re running - if both are, quit both - if only one is, offer to launch or quit both - if neither are, launch both. Simple so far, using
tell application "System Events"
set runningApps to name of every application process
if (runningApps contains "ThisApp") and (runningApps contains "ThatApp") then
-- etc...
…but… ThatApp is a menu bar app that doesn’t appear in the runningApps list, dammit! I guess it’s a daemon, rather than an app as such.
So: anyone out there know how to script to detect ThatApp, which is listed in the User Processes of Process Viewer, but not in the System Events running applications list…
Thanks, but this doesn’t work either.
I wrote a version of it that displays all process names in a dialogue, and the process that’s running in the menu bar comes with a blank name in this list, even though it has a name in the Process Viewer! I’m baffled by this. There must be some way of accessing the name that isn’t kept in ‘name of item’, but I can’t find it.
I’m beginning to find AppleScript a bit too arcane - it seems to me that every time I try to do something that ought to be simple, it turns out that I left out the eye of newt or something. I can’t wait for a really good book on it to come out…
Well, depending on which of the two commented-out lines you actually use as running code, you get two very different results, at least in 10.2.8.
The first version, which only allocates a number to each line, gives me 34 items, and 34 lines. The second version, which is exactly the same except that it also appends the process name onto the number, says that there are 34 items, but then only lists 14 lines.
So what’s going on here? When I use my code to try to get any process whose name is as list
it only works for names that appear in the list generated by my code above - there are, apparently, a number of background processes that not only have no name as that particular property, but won’t allow themselves to be listed. What’s going on, and how do I get these processes? Is there some way to get them as a list of PIDs and get the name properties from the PID? I’m baffled.
You’re right that AppleScript is hard to understand in the beginning. Takes a lot of experience and reading comprehension. You can get a lot of experience by working your way through the statements of your script and looking at the results. The hard part about this problem is that the applications name is “WeatherPop” and the process name is “WetherPopApp”. This is not AppleScript’s fault. Anyway, I think this should work:
property app_list : {“WeatherPop”, “Terminal”}
tell application “Finder”
– might get an error here if both aren’t running
– depends on version
set my_procs to (name of every process whose ¬
name is “WeatherPopApp” or name is “Terminal”)
end tell
if my_procs is {} then
LaunchApps(app_list)
else if (count my_procs) is 1 then
display dialog “Only one app is running.” buttons ¬
{“Cancel”, “Quit Both”, “Run Both”} default button “Cancel”
set the_result to result
if button returned of the_result is “Quit Both” then
QuitApps(my_procs)
else
LaunchApps(app_list)
end if
else
QuitApps(my_procs)
end if
– quits applications whose names are in the list
– needs error checking for modular
on QuitApps(app_list)
repeat with this_app in app_list
set is_running to false
tell application “Finder”
if exists process (contents of this_app) then
set is_running to true
end if
end tell
if is_running then quit application this_app
end repeat
return
end QuitApps
– launches applications whose names are in the list
– needs error checking for modular
on LaunchApps(app_list)
repeat with this_app in app_list
tell application this_app to launch
end repeat
return
end LaunchApps
Note that you cannot ‘activate’ the “WetherPop” application because it runs faceless process in your case (i.e. running the app installs the menu item).
I made a little mistake there. Used the name of the property in the subroutine. I’m kind of rushhing now to go to sleep so did a quick fix. Will look at it again tomorrow or you can debug it.
property app_list : {“WeatherPop”, “Terminal”}
tell application “Finder”
– might get an error here if both aren’t running
– depends on version
set my_procs to (name of every process whose ¬
name is “WeatherPopApp” or name is “Terminal”)
end tell
if my_procs is {} then
LaunchApps(app_list)
else if (count my_procs) is 1 then
display dialog “Only one app is running.” buttons ¬
{“Cancel”, “Quit Both”, “Run Both”} default button “Cancel”
set the_result to result
if button returned of the_result is “Quit Both” then
QuitApps(my_procs)
else
LaunchApps(app_list)
end if
else
QuitApps(my_procs)
end if
– quits applications whose names are in the list
– needs error checking for modular
on QuitApps(this_list)
repeat with this_app in this_list
set is_running to false
tell application “Finder”
if exists process (contents of this_app) then
set is_running to true
end if
end tell
if is_running then
try
quit application this_app
end try
end if
end repeat
return
end QuitApps
– launches applications whose names are in the list
– needs error checking for modular
on LaunchApps(this_list)
repeat with this_app in this_list
tell application this_app to launch
end repeat
return
end LaunchApps
I tried your script, Kel, and it didn’t work either - then I followed a hunch (i.e. had another look when it wasn’t 3 a.m.) and opened the Process Viewer. The process name that my (and your) script couldn’t find was “Mouse Position Menu” - yet there it was in the PV window. Then I changed the width of the Name column, and… it’s called “Mouse Position Menu 1.2”…
so now your script works, and my script works too - but yours is more elegant (I hadn’t yet got around to putting subroutines in mine, I just had a load of quick and dirty tells), so thanks for the code, which I will be harvesting for other little projects.
I went back to the original script and just added the error handler in the quit subroutine. I think it was erroring because the tell block sends an implicit run command before it quits the background app. Not really sure what’s going on with this app but wihth the error handler it works. So here’s the mod:
property app_list : {“WeatherPop”, “Terminal”}
tell application “Finder”
– might get an error here if both aren’t running
– depends on version
set my_procs to (name of every process whose ¬
name is “WeatherPopApp” or name is “Terminal”)
end tell
if my_procs is {} then
LaunchApps(app_list)
else if (count my_procs) is 1 then
display dialog “Only one app is running.” buttons ¬
{“Cancel”, “Quit Both”, “Run Both”} default button “Cancel”
set the_result to result
if button returned of the_result is “Quit Both” then
QuitApps(my_procs)
else
LaunchApps(app_list)
end if
else
QuitApps(my_procs)
end if
– quits applications whose names are in the list
– needs error checking for modular
on QuitApps(this_list)
repeat with this_app in this_list
try
quit application this_app
end try
end repeat
return
end QuitApps
– launches applications whose names are in the list
– needs error checking for modular
on LaunchApps(this_list)
repeat with this_app in this_list
tell application this_app to launch
end repeat
return
end LaunchApps