AppleScript GUI scripting line that only works 100% when I watch it

No, really.

I have an AppleScript, that executes every night. It mounts a remote volume, moves a set of files to a specific location on that remote volume, and unmounts the remote volume. Works great. It even writes script status out to an event log, and has an idle handler to wait for large file copies to complete. All of this works perfectly, every night.

In the middle of the script, there’s a statement that uses GUI Scripting (which is turned on on that machine)… and there’s where the problem comes in. This single line (well, three lines with the tell statement) works perfectly if I trigger the script manually, and often will work the night after I make some sort of change or tweak to try to get it to work. But other than that, that line just quietly fails, and I can’t figure out why. Here’s the line, in context:


	[scripting elements up here that, among other things, selects the correct folder so that it's selected and visible in the Finder]

	tell application "System Events"
		tell process "Finder" to click (first menu item of menu 1 of menu bar item 3 of menu bar 1 whose name contains DaySpecificFolder)
	end tell

That should trigger the “Create Archive of ‘DaySpecificFolder’” menu item every time. Yet it only does sometimes.

Does anyone have any experience with this? Is there anythign to GUI scripting that I need to do to tweak this to work all the time? Is there a better way to get this archive made within this script? Any help or suggestions are appreciated!

Steve
fmp.developer@gmail.com

Hi Steve,

maybe you should activate the Finder before choosing a menu item

activate application "Finder"
tell application "System Events"
	tell process "Finder" to click (first menu item of menu 1 of menu bar item 3 of menu bar 1 whose name contains DaySpecificFolder)
end tell

Stefan,

Maybe I’m not being clear; I have a whole bunch of scripting before and after this line, and yes, at the moment at which this line occurs, the Finder is activated, the enclosing folder is open, the correct folder is selected - all of this happens every time, quite reliably. It’s just that the GUI scripting line is most often (but not always!) ignored.

I could post the entire script here, if that’s appropriate. It’s not small. Please advise.

Thanks!

Steve

Can you post only a portion of the script, which is more significant for the problem.
But you might also post the whole one

OK, I’ve pared this down a little - I’ve removed the error logging and replaced some of the specific variables (like file paths and passwords and such) with [filepath here] kinds of things.



on check_progress()
	tell application "Finder"
		repeat while ((first window whose class is «class prwd») exists)
			delay 5 -- change to higher increment if we need this to be longer
		end repeat
	end tell
	delay 5 -- juuuust in case
end check_progress

----

on run
	-- [stuff here to get the date and time]
	set DaySpecificFolder to "FMS_Daily_Backup_" & DayNumberOfWeek & "_" & DayOfWeek
	
	ignoring application responses
		tell application "ScreenSaverEngine" to quit
	end ignoring
	-- should kill the screensaver, if it's running
	
	tell application "Finder"
		activate
		make new Finder window -- just to make debugging a little more visible
		mount volume "[IP and name]" as user name "[username]" with password "[password]"
		set LocalBackupFolder to folder [filepath_here]
		set SourceFolder to folder DaySpecificFolder of LocalBackupFolder
		set DestinationParentFolder to folder [filepath_here]
		activate
		select folder DaySpecificFolder of LocalBackupFolder
	end tell
	
	tell application "System Events"
		tell process "Finder" to click (first menu item of menu 1 of menu bar item 3 of menu bar 1 whose name contains DaySpecificFolder)
	end tell
	
	check_progress() -- Wait for any progress bar to disappear.
	
	tell application "Finder"
		-- [stuff here that moves the zip file to the remote volume and trashes the original]
	end tell
	
	check_progress() -- Wait for any progress bar to disappear.
	
	tell application "Finder"
		duplicate SourceFolder to DestinationParentFolder replacing yes
	end tell
	
	check_progress() -- Wait for any progress bar to disappear.	
	
	tell application "Finder"
		eject "[remote volume here]"
		repeat while window 1 exists
			close window 1
		end repeat
	end tell
	
end run


All of that works, except the “System Events” portion; most often, that part simply fails to execute, though the remainder of the script still executes just fine like clockwork. Sometimes - sometimes - we get a zip file out of it, like we’re supposed to. And if I manually trigger this AppleScript, I’ll get a zip file 100% of the time.

Hi Steve,

forget this annoying GUI scripting and use a shell command to create the zip file


...
tell application "Finder"
	set LocalBackupFolder to [filepath_here]
	set SourceFolder to folder DaySpecificFolder of LocalBackupFolder
	set fName to name of SourceFolder
end tell
set item_path to quoted form of POSIX path of (SourceFolder as alias)
set destination_path to quoted form of (POSIX path of (LocalBackupFolder as Unicode text) & fName & ".zip")
do shell script ("/usr/bin/ditto -c -k -rsrc --keepParent " & item_path & " " & destination_path)
...

What I can imagine is that you call (the old bugger, ready to retire ;)) Finder too fast again in:


....
 select folder DaySpecificFolder of LocalBackupFolder
   end tell
   
   tell application "System Events"
       tell process "Finder" to click (first menu item of menu 1 of menu bar item 3 of menu bar 1 whose name contains DaySpecificFolder)
   end tell

After selecting “select folder DaySpecific…”, the old beast needs some time to get its menu’s updated, otherwise there is no “first menu item… … …”
I suggest to pause a couple of seconds after “select” (don’t pause Finder, but pause your script with tell me to do shell script “Sleep 2” or alike)

Cheers.

StefanK

nice point… always best NOT to use GUI scripting if you can avoid it …
:cool:

mm

Ah - excellent! I was hoping there was a more robust way to go about making the zip archive. The GUI scripting is so very brittle (as I’ve seen).

Question, though: when I use the GUI scripting, I have a progress bar that pops up while the zip is happening, and my idle handler waits based on the presence of that progress window. I’m zipping a couple of gigs of stuff, and that can take longer than AppleScript’s timeout; does OS X tell the AppleScript when the shell script is complete? How does my script know when to continue?

Thanks!

Steve

I guess there is no timeout, because a shell script call doesn’t send any Apple Events.
The script continues after the zipping is complete