Quick question on detecting/changing process status

Is there any way to have a script be launched when an application/process quits? How about if the script is already running?

I’d like to be able to create scripts which invisibly change system preferences to accommodate the needs of certain media applications and games, but which are also able to revert to the original settings once the finicky program is done.

Thanks for any help you’re able to give!

There was an application specially designed to launch stuff when under user-defined circumstances, such as “application x quit/launch” or whatever. But, basically, it would be easy creating your own.
Stupid demo sample (save as stay-open):

global app_to_monitorize

on run
	set app_to_monitorize to "MSIE" --> signature of Internet Explorer, eg.
end run

on idle --> execute this periodically
	tell application "Finder" to creator type of processes --> list of apps running (creator types, safe)
	if app_to_monitorize is in contents of result then --> IE is running!
		killIt() --> do whatever
	else
		launChIt() --> do whatever
	end if
	return 2 --> execute this every 2 seconds
end idle

to killIt()
	tell application "Finder" to set msie to name of first process whose creator type is app_to_monitorize
	tell application msie to quit
end killIt

to launChIt()
	tell application "Finder" to open (application file id app_to_monitorize)
end launChIt

Thanks! That’s really helpful. For most apps, this will be fine as a sort of wrapper script – launch the script instead of the app, have it self quit in the idle handler if the wrapped script is gone.

But I have a handful of media applications tied to a remote control and the sound input setting. The problem is that when the media applications quit, they erroneously change the sound setting. If I use the remote as is, it won’t launch the script (obviously.) If I trick the operating system into thinking that the script IS one of the media apps, then most of the buttons won’t work. I wonder, is there any way to tie a script to an application’s behavior without staying open or idling? Plus, I might run the script on a really old, slow computer, and wouldn’t want to bog it down any further.

UPDATE: After some fiddling with creator types and scripts, I’ve determined that I CAN replace my media application with the script – but this revealed another problem. One button on the remote toggles a particular program, making it active and frontmost if not frontmost and quiting it otherwise. The program in question is the Apple Video Player – which is AppleScriptable but has no quit routine.

So in the case that the player quits before the script, no problem → the idle handler detects the change and self quits. But if the remote buttons are pressed, they call up what they believe to be the player, which is actually the script. I thought I’d just tell the script that if it is ever frontmost while the video player is present, quit the player first, then itself. But the player has no built-in quit routine – the script keeps failing on attempting to quit it. Any suggestions? Current code follows (sorry, don’t know how to format):

global app_to_monitorize
global app_to_kill
global oldSound

on run
set app_to_monitorize to “mtv3” → signature of Apple Video Player.
set app_to_kill to “mtv2” → signature of script (modified to be recognized by remote)
set oldSound to sound input source → this instruction is available with a scripting addition
if oldSound is not 5 then
sound input source 5 → “5” is CD/FM/TV, required for sound in Apple Video Player
end if
tell application “Finder”
open file “Apple Video Player” → of appropriate path
end tell
end run

on idle → execute this periodically
tell application “Finder” to creator type of processes → list of apps running (creator types, safe)
if app_to_monitorize is not in contents of result then → Apple Video player is not running
restoreSounds() → do whatever
else
tell application “Finder” → if this script is frontmost then
set mtv2 to first process whose creator type is app_to_kill
get frontmost of process (mtv2 as text)
end tell
if result is true then
killMe()
end if
end if
return 2 → execute this every 2 seconds
end idle

to killMe() →
tell application “Finder” to set mtv3 to name of first process whose creator type is app_to_monitorize
tell application mtv3 to quit
restoreSounds()
end killMe

to restoreSounds() → restore previous sound input setting before quitting
tell application “Finder” to sound input source oldSound
quit
end restoreSounds

You might consider using “ScriptSynch” to accomplish your needs. It is a system extension which launches a script (application) or other application when a “given” application either launches or quits. I use it to “trash” explorer history when I quit my browser, change monitor depth when I launch or quit certain game (because the games require a monitor depth which is different from my “normal” monitor depth) and many other things.
You can get “ScriptSynch” at http://www.macscripter.net/tools.html

Hope this simplifies what you want to do. It should prevent the need for “complicated” idler handler scripts.

:o

Hi,

Also, you may be able to just script locations. I didn’t have the the time to read all the posts and your post deeply but that would make it very simple.

gl,

Using ScriptSync I’ve almost got a working solution. Here were the various complications I faced:
1.) The sound settings can only be changed BEFORE Apple Video Player (AVP) launches and AFTER it has quit
2.) The remote control, which should have the ability to launch the AVP OR if already running and not frontmost, bring to front OR if frontmost, quit it. But if I want the script to run instead before the AVP, I have to replace the AVP with the script – meaning that pressing the remote button brings THE SCRIPT frontmost or quits it.
3.) In order for the other remote control functions to work, this script must stay open as long as AVP is running.
4.) AVP’s dictionary has no “quit” command, so as far as I know, there is no way to make it quit via an AppleScript. (I tried, and the script would crash on each quit attempt.)
5.) I’d like this to be idiot proof, so any order of launching and quitting components, not just the prefered order, gets the desired response.

My solution: three scripts, two of which are tied to ScriptSync.

The first, “Launcher” changes the settings as necessary, launches a second script, called “Shell,” and then begins an idle loop. From here on, Launcher is merely mimicing the remote – if Launcher is brought to front, it brings the AVP to front, unless AVP was the last front application, in which case Launcher tells Shell to quit before itself quitting. Obviously, a stay open script.

Shell consists entirely of an idle loop which checks if it is frontmost. If it is and AVP is still running, AVP is set to frontmost. Again, this is a stay open script.

Shell has a “tied to launch” alias to the AVP in the ScriptSync folder. Therefore, when Shell launches, the AVP launches, when Shell quits, the AVP quits. (This gets around problem 4 from above.)

The AVP has a “tied to quit” script in the ScriptSync folder. This script, called “QuitScript” first restores the sound settings to the previous one, then checks the other scripts. If Launcher or Shell are still running, they are quit.

So far, so good, if a bit awkward. Launcher stays open and handles the remote, settings are guaranteed to be changed only before and after AVP’s run, and the scripts can quit AVP by quitting the otherwise useless Shell script. You can start from either Launcher or Shell and get the proper settings and TV performance. The one problem is if the user runs Launcher first, the Shell idle script doesn’t seem to run – you can bring Shell to the front and it just stays there.

Is it impossible to have two separate scripts running idle handlers concurrently? Is there an easy way to approximate this?

Is there any way to run scripts invisibly (not in the Application Switcher) yet still have frontmost values?

Kel – what is “scripting locations” and how do I go about doing it?

Can anyone think of a cleaner solution to my 5 problems?

Thanks for all your help guys!

You can easily create a FBA (faceless background application) using Leonard Rosenthol’s “Script FBA”, vid http://macscripter.net/tools.html#t21

If you can’t “quit” AVP, you can still “force quit” it. You can use Akua Sweets’ command “abort immediately”, vid http://osaxen.com/akua_sweets.html

Thanks, but neither seem to do what I need – I don’t want a constantly running system extension, just an app that runs invisibly for the duration of AVP’s run, then quits. As for “abort immediately,” it would have been great, but the Apple Event timed out every time I tried it but the last – when it force quit the TV Tuner card extension instead of the AVP.

One last question (hopefully) → is there any way to determine which application/process was previously frontmost? An ordered list of some kind?

Currently I’m updating a variable in an idle-handler when AVP is frontmost, then checking it when the script becomes frontmost. (Necessary to emulate the remote – if last frontmost was AVP and I am now active, quit both. Otherwise, make AVP active.)