Hi all,
I’m having trouble. First let me describe what I want to do.
I am designing a software package for a permanent museum installation. The main software runs as a startup item. As it runs, it “touches” a file called “theplaceisrunning” every minute. I want an applescript to run in the background, checking to make sure that this file has been touched within the last few minutes. If it hasn’t, I want the machine to reboot. But if it has been rebooted within the last five minutes (indicative of a more serious problem) I want the machine to shut down. All of this has to happen without any human interaction. Here’s what I have so far:
on idle
tell application "Finder"
if (((current date) - (modification date of (file "theplaceisrunning" of folder "the place" of the desktop))) ≥ (2 * minutes)) then -- this file is touched every minute from within max
if (((current date) - (modification date of (file "rebooted" of folder "the place" of the desktop))) ≤ (5 * minutes)) then -- this file is touched on loadbang from within max
set rebootdiag to display dialog "It appears as though Max has stopped running, and has rebooted within the last 5 minutes. I will shutdown in 30 seconds, unless you click Cancel." buttons {"Cancel", "Shutdown"} default button "Shutdown" with icon caution giving up after 30
if gave up of rebootdiag is true then
set button returned of rebootdiag to "Shutdown"
end if
else
set rebootdiag to display dialog "It appears as though Max has stopped running. I will reboot in 30 seconds, unless you click Cancel." buttons {"Cancel", "Reboot"} default button "Reboot" with icon caution giving up after 30
if gave up of rebootdiag is true then
set button returned of rebootdiag to "Reboot"
end if
end if
if button returned of rebootdiag is "Reboot" then
tell application "System Events"
restart
end tell
end if
if button returned of rebootdiag is "Shutdown" then
tell application "System Events"
shut down
end tell
end if
end if
end tell
if button returned of rebootdiag is "Cancel" then
quit
end if
return 60
end idle
But the problem is, even though I have saved it as a “stay open” application, the script does not do anything unless I click on its icon in the dock.
I think I’m answering the wrong question here, but anyway:
The OS X Finder’s not very good at updating its information about files, so it may simply be assuming that the modification dates are the same as the last time it bothered to look. You could try inserting an ‘update’ command just before those tests:
on idle
tell application "Finder"
update files of folder "the place" of the desktop
if (((current date) - (modification date of (file "theplaceisrunning" of folder "the place" of the desktop))) ≥ (2 * minutes)) then -- this file is touched every minute from within max
-- etc.
end if
end tell
end idle
But in fact you don’t need to use the Finder. The StandardAdditions’ ‘info for’ command can get the information you want too:
on idle
set now to (current date)
set TPfolder to (path to desktop as Unicode text) & "the place:"
if (now - (modification date of (info for alias (TPfolder & "theplaceisrunning"))) ≥ (2 * minutes)) then -- this file is touched every minute from within max
-- etc.
end if
end idle
Your test for “Cancel” is outside the ‘if’ blocks where the ‘rebootdiag’ variable is set. If the conditions are such that the dialogs aren’t displayed, trying to access this non-existent variable will cause an error. The test will, in any case, not work if you’re using an English language system because a “Cancel” button always generates a “User canceled.” error. It doesn’t return a result you can test. So you need to trap the error:
on idle
set now to (current date)
set TPfolder to (path to desktop as Unicode text) & "the place:"
if (now - (modification date of (info for alias (TPfolder & "theplaceisrunning"))) ≥ (2 * minutes)) then -- this file is touched every minute from within max
try
if (now - (modification date of (info for alias (TPfolder & "rebooted"))) ≤ (5 * minutes)) then -- this file is touched on loadbang from within max
set rebootdiag to display dialog "It appears as though Max has stopped running, and has rebooted within the last 5 minutes. I will shutdown in 30 seconds, unless you click Cancel." buttons {"Cancel", "Shutdown"} default button "Shutdown" with icon caution giving up after 30
tell application "System Events"
shut down
end tell
else
set rebootdiag to display dialog "It appears as though Max has stopped running. I will reboot in 30 seconds, unless you click Cancel." buttons {"Cancel", "Reboot"} default button "Reboot" with icon caution giving up after 30
tell application "System Events"
restart
end tell
end if
on error number -128 -- "User canceled." error
quit -- Tell this script application to quit when it's finished running the script.
error number -128 -- Stop the script now.
end try
end if
return 60
end idle
Nigel and Adam,
Thank you both for your help. Both of you provided pieces of my solution. The “on run” handler made the app do its job, and the update does make finder’s answers reliable. Nigel, also thank you for the tips on the user cancel, and the modification date additions outside of finder.
I did need to tell my script to activate in order for the dialog box to display.
Below is my solution (with the shell reboot in case an application isn’t responding and the logout process is interrupted).
Thanks,
jim
on run
delay 30
end run
on idle
set otherbutton to ""
set now to (current date)
set TPfolder to (path to desktop as Unicode text) & "the place:"
set mod_date to (modification date of (info for alias (TPfolder & "theplaceisrunning")))
set reboot_date to (modification date of (info for alias (TPfolder & "rebooted")))
if ((now - mod_date) ≥ (2 * minutes)) then -- this file is touched every minute from within max
activate
try
if ((now - reboot_date) ≤ (5 * minutes)) then -- this file is touched on loadbang from within max
set rebootdiag to display dialog "It appears as though the place has stopped running. The last time it was running was " & (mod_date as string) & ", but it is now " & ((current date) as string) & ". It was rebooted within the last 5 minutes (at " & (reboot_date as string) & "). I will shutdown in 30 seconds, unless you click Cancel." buttons {"Cancel", "Shutdown"} default button "Shutdown" with icon caution giving up after 30
try
tell application "System Events"
shut down
end tell
on error
do shell script "shutdown now" password "xxx" with administrator privileges
end try
else
set rebootdiag to display dialog "It appears as though the place has stopped running. The last time it was running was " & (mod_date as string) & ", but it is now " & ((current date) as string) & ". I will reboot in 30 seconds, unless you click Cancel." buttons {"Cancel", "Reboot"} default button "Reboot" with icon caution giving up after 30
try
tell application "System Events"
restart
end tell
on error
do shell script "shutdown -r now" password "xxx" with administrator privileges
end try
end if
on error number -128
quit
error number -128
end try
end if
return 60
end idle