Simple Script

I know, I know - really, I didn’t want to turn to anything shell (as handy as it can be, I realize). So back to the topic - if someone has an AppleScript angle to offer, I’m all ears. Especially since the shell suggestions presented here, handy as they are, are eclipsed by the idle loop going AWOL. :frowning:

The first incarnation used not with (exists process appname) but the time was still 5. I’ll kick that up to 30 and try the original again. Thanks!

OK - tried the switcheroo with using “not” - no dice. Tried increasing the timeout. Ditto on the no dice.

However, this time (using 5 seconds, 10 or even 30) I just let it run. I didn’t try to force quit it for a change. Eventually I got the same thing I usually get when I force quit it: A message box with “Apple Event Timed Out.”

I didn’t mention this before because I thought it was a consequence of my doing a force quit. So much for that assumption.

So … what Apple Event, pray tell …

Another stab, have you tried using the PID# instead of the app name as the variable, you could even try increasing it by 1 (e.g., PID = 1447 + 1) since you mentioned that it releases that PID and comes back as 1 higher

set x to do shell script "ps cax | awk '/Learning/{print $1}'"
x + 1

It really sounds as though the app itself is the problem, so you may not be able to get around this one ;¬(

One more stab, try using the “Finder” instead of “System Events” in your tell block.

What about moving some of the code outside of the System Events tell block:

property appname : "Reading and Phonics"

on run
	do shell script "~/bin/cscreen -x 800 -y 600"
	activate application appname
end run

on idle
	tell application "System Events" to set current_apps to name of processes
	if current_apps does not contain appname then
		try
			do shell script "~/bin/cscreen -x 1440 -y 900"
			quit me
		end try
	else
		return 10
	end if
end idle

Jon

First off, the PID number changing suggests that there’s some kind of launcher app at work here. [Btw, it may or may not have the same name (i.e. there could be an invisible character in the name, trailing spaces, etc.), so don’t just assume it is the same just because it looks the same.]

Well that’s a significant question, and when you can answer it, you may have solved the riddle to this problem.

Try this:

Note: I chose 35 in the delay arbitrarily; choose some number greater than the time it takes to switch PID’s. A factor of 1.5 to 2 would be a good choice.

Thanks for those suggestions! Finder was the first thing I was using, but then I saw someone write one with System Events and thought switching to that would help.

I like the PID increment idea, except I’m mildly paranoid that the one day he tries it, some other process will fork or start anew right in the middle and botch that up. Still, worth a shot!

Jon, thanks for pointing out that there are try blocks in AppleScript - fantastic. I tried your suggestion as well, but no luck. It seems like the idle block just isn’t getting called for some reason. I can put a display dialog in here every minute and it’s a no-show. OTOH, I like your page of AppleScripts and I’m going to learn from that! Maybe I’ll finally write something using AppleScript Studio. :slight_smile:

RainyDay, another good use of the try block. It just never seems to reach it in the first place. Now, as I understand it, when the run block finishes (is that the right terminology in this case, blocks?) it should call idle right away, and then whatever idle returns, it uses that as the delay before calling again (more or less). Maybe when CGR&P is called, that first idle call is never made or …

Could CGR&P be goofing around under the hood with Apple Events and messing up some kind of message queue? Perhaps it’s flat-out messing up the idle loop? (I’m calling their support line at 11. Then the real fun begins. I oughta transcribe it - heh-heh …)

More suspicious evidence. I had to reboot at one point. I almost never have to reboot. Some funny business in the Finder or somewhere else under the hood. Just weird behavior I’ve never seen before I started experimenting with this.

Are you saving this script as an application and then running it by double-clicking on it (not from within Script Editor)? Without doing this, the idle handler will never be called.

Jon

Yes, it’s saved as a stay-open app and then run outside of Script Editor.

There is a difference between Jon’s use of it and mine: I put the quit me outside of it. I’m assuming that if the do shell script "~/bin/cscreen -x 1440 -y 900 fails the first time through, it’ll fail on subsequent passes too, so you’ll want to quit rather than get stuck in an infinite loop. Jon’s use assumes that it will, at some time, succeed. The best approach might be to put an error handler in there which brings up a dialog and asks the user whether to try again or quit? If it’s try again, then return 30, or some other sufficiently long delay.

The correct terminology, in this instance, is not “block” but “handler.” “Block” is sometimes used to refer to smaller sections of code, like a “try” block, or “if” block. Usually some compound statement which ends with an “end” statement.

You are correct in how the flow should occur. Try putting a beep 3 right after the CGR&P call to see if control returns right away or not. If not, embed the call in an ignoring application responses block like this:

ignoring application responses
        tell application "Reading and Phonics" to activate 
end ignoring 

It sounds to me – if the idle handler is never called – that your run handler is never finishing. Put a beep 2 preceeding the delay 35. If you don’t hear the beeps, i’ll bet it’s the CGR&P call, alright. Of course the ignoring application responses should take care of it if that is the problem.

One thing to try, if it is the cscreen call (which i tend to doubt) is to make the call like this:

try
	   do shell script "~/bin/cscreen -x 800 -y 600" 
on error the error_message number the error_number
	display dialog "Error: " & the error_number & ". " & the error_message buttons {"OK"} default button 1
end try

That will yield some diagnostic info.

I’ve had the Finder lock up on me before, where a force quit was not possible and a reboot was the only recourse. Has usually been related to using its “connect to server” option to connect to a finicky FTP server.

Aye. Of course, cscreen hasn’t been failing at all. That’s the most reliable part! :slight_smile:

Can’t believe I called it a block - I should’ve known better. Of course it’s a handler. Thanks very much for the correction.

So that was it. It wasn’t so much that the idle handler wasn’t getting called but that run was never completing. Moreover, your suggestion to use ignoring application responses did the trick. Bravo! I learned something entirely new.

The final source (for now):

(* Must save as a Stay Open Application in Script Editor *)
property appname : "Reading and Phonics"
on run
	do shell script "~/bin/cscreen -x 800 -y 600"
	ignoring application responses
		tell application appname to activate
	end ignoring
end run
on idle
	tell application "System Events"
		if not (exists process (appname)) then
			do shell script "~/bin/cscreen -x 1440 -y 900"
			quit me
		end if
	end tell
	return 2
end idle

Again, thanks tons to everyone for weighing in on this one (… and feel free to keep doing so - or, hmm, yeah, move on ).

Well, i didn’t want to raise your hopes prematurely, but i had a sneaking suspicion it just might do the trick.

Now i’m curious if this will work (eliminating your idle handler):

(* No longer needs to be a Stay Open Application, nor an App at all *) 
property appname : "Reading and Phonics" 
on run 
     do shell script "~/bin/cscreen -x 800 -y 600" 
		with timeout of 0 seconds
			tell application appname to activate
		end timeout
     do shell script "~/bin/cscreen -x 1440 -y 900" 
end run 

I think the with timeout of 0 seconds tells the activate call to wait forever, and i’m hoping it’ll return from the call when the app quits. When the app quits, control will either come back to your AppleScript (as i hope), in which case the second cscreen call is executed, or it will never come back, and your AppleScript is caught waiting for an event which will never occur. If it works, this approach beats the idle handler approach (less system overhead, and may be a regular compiled script).

I like it! A lot more elegant, and it sheds a lot of excess pounds. :slight_smile:

Alas, it never comes back. In fact, this time I have to Force Quit the script editor. Hmm … maybe put ignoring application responses in there? I’ll try it.

HAHAHA - OK, so now I grok that ignoring part a bit more. It ignores the response and plows on through, resetting the screen res. So much for that.

Wow, now I’m curious myself .

Ha ha! That was a good trick! :smiley:

Alas, too bad the shorter script didn’t work! :cry: I suspect the problem is that CGR&P isn’t scriptable and so doesn’t respond to the activate command, thus hanging the script until it times out (should be in about 60 seconds). CGR&P launches because of an implied run command (a command which all applications respond to, scriptable or not). Replacing activate with run might eliminate the need for the ignoring application responses, but hey, it works already, so why sweat it?

I’m surprised you had to force-quit the Script Editor. The stop button should have been sufficient to halt the script.

Good trick, yeah! I’m sure it had some entertainment value in there somewhere .

Well well. I can’t load a dictionary for CGR&P in Xcode, ergo …

Yet another subtlety - run vs. activate. Sure, why not? Other things I’m going to try are setting the volume, disabling the active screen corners, and then restoring them later on.

As for Script Editor, it wasn’t responding to any mouse events. Zero. The window manager was happy - I could move the window, but that was about it. Couldn’t even get at the menu.


Yes it did; definitely worth the price of admission! (Of course i’ve never been there myself! )

Don’t you just love it?

That surprises me. Be that as it may, the default time-out should be around 60 seconds, so control should have come back to you if you were willing to wait. Not that it matters now, but in the future you might have some unsaved changes you don’t want to nuke with a forced-quit. Just FYI.

I gave up waiting after about three minutes. I figured by then it was beyond saving. Bizarre.

I am wondering if anyone out there could help me out on building a simple script. I don’t know too much about scripting so hold tight.

I am printing a PS file over the network into a folder on a server. I need a script that automatically takes any file that appears in that folder and moves it to the printer’s RIP folder. Only the drop boxes are shared on our network, so I can’t directly print to the RIP folder. And I don’t want have the RIP folder shared in our network

I will list exact folder paths to make it easier.

I need any files that get added to
server/users/filserver/public/drop box/lop file server/to print

and move it to
server/applications/hp designjet 20ps RIP/jobs/hp designjet 20ps

To avoid any errors from duplicate named files appearing in the RIPs folder… i was thinking you could (if you are feeling extra nice) script it to trash the file after it is printed in the RIP…

OR

add a suffix to the end of the file name (.a, .b, .c etc)

Though either of these extras are just icing on the ca

this might be getting off topic, but just incase it helps. i know of two one liners in terminal that will kill a process by name.

in terminal
killall Mail
will kill any application with the name Mail.

it should work with any application name

another way to do it is:

ps -aux | grep Mail | grep -v grep | awk ‘{print $2}’ | xargs kill

again, replace “Mail” with a process name.