#include <File.au3>
; _ReplaceStringInFile
#include <Array.au3>
; _ArrayToString
#Include <Date.au3>
; _Now
#cs
2008
AutoIt v3
http://www.autoitscript.com/autoit3/
Purpose: run an pausable fortran executable when the screensaver runs,
pausing the fortran program when the screensaver does not run.
overview:
two command-line arguments are passed to this executable: directory number (1 or 2)
and the name of the screensaver (like logon.scr)
Next the "seed.input" file is read to determine the sign (positive or negative)
Positive = GOOD, as it means seed file was initialized to correct state if running
for the first time, or if "pause" was invoked then quasi1d.exe exited cleanly.
Negative = BAD, as it implies incorrect initialization state or the quasi1d was
interrupted during the previous run (and thus did not exit cleanly)
negative means exit, positive means continue
If the screensaver is detected, continue to the primary loop.
[Start loop]
Seed is postive. Set to negative and start quasi1d program
if the screensaver does not exist, then pause quasi1d by setting seed to positive
wait for screensaver to exist
[end loop]
#ce
;AutoItSetOption("TrayIconDebug", 1)
; no tray icon
TraySetState(2)
#cs
Note: normally the user can not kill the processor in task manager since
in practice the user doesn't have local admin rights
Allow the local user (luser) to end this program
^ = control
+ = shift
! = alt
Note: terminating the program interrupts whatever is happening (no clean exit)
so terminating with the key combination is better, as it allows for a clean exit
#ce
; CONTROL+SHIFT+ALT+ESCAPE
HotKeySet("^!+{ESC}", "Terminate")
; not in use:
;HotKeySet("^!+p", "TogglePause")
; run this program below normal priority
ProcessSetPriority(@AutoItPID, 1)
; not sure why the logon_mon runs at 14% processor. It's normally at "ProcessWait".
; it would be good to kill any pre-existing version
; doesn't work in au3
;ProcessClose("watcher_test.exe")
; would need to be done in an external batch file
; need two arguments
; -which node are we on, 1 or 2?
; -what's the name of the screen saver?
if ($CmdLine[0]<>2 ) Then ; not passed two arguments
; note that we won't be able use use the normal '"C:\researchdump" & $node_num & ' for this, so default to 1 which should exist regardless of whether there's 1 or 2 CPU
$CLI_arg_ERROR_file = FileOpen("C:\researchdump1\error_incorrect_number_of_CLI_arg_%computername%_.error", 1+8 ) ; 1 = Write mode (append to end of file) ; 8 = Create directory structure if it doesn't exist
; Check if file opened for writing OK
If $CLI_arg_ERROR_file = -1 Then ; a backup method if the error file has an error. Downside is that a cmd window opens for each line
Run(@COMSPEC & " /c echo ERROR: unable to open error file >> C:\researchdump1\error_incorrect_number_of_CLI_arg_%computername%_.error" )
Sleep(200)
Run(@COMSPEC & " /c echo Also, two CLI arguments are needed - which node and name of screensaver >> C:\researchdump1\error_incorrect_number_of_CLI_arg_%computername%_.error" )
Sleep(200)
Run(@COMSPEC & " /c echo logon_mon exiting (quasi1d was not started) >> C:\researchdump1\error_incorrect_number_of_CLI_arg_%computername%_.error")
Exit
EndIf
FileWrite($CLI_arg_ERROR_file, "two CLI arguments are needed - which node and name of screensaver" & @CRLF)
FileWrite($CLI_arg_ERROR_file, "logon_mon exiting at " & _Now() & ". (quasi1d was not started)" & @CRLF)
FileClose($CLI_arg_ERROR_file)
Exit
EndIf
;Run(@COMSPEC & " /c echo I got here, " & $CmdLine[1] & $CmdLine[2] & " >> C:\researchdump1\actions.log")
$node_num = $CmdLine[1] ; 1 or 2
$screensaver = $CmdLine[2] ;"logon.scr" (windows) or "UMR_logon.scr" (slideshow)
; could pass the name of the program here to make it more general
$researchdump = "C:\researchdump" & $node_num & "\" ; example: c:\researchdump1\
$seed_file = $researchdump & "seed.input" ; example: c:\researchdump1\seed.input
$seed_status_file = "initialized_seed_status_%ComputerName%_" & $node_num & "_.log"
$path_seed_status_file = $researchdump & $seed_status_file
$pausable_program_name = "quasi1d_many_scatterer" & $node_num & ".exe"
; now that we have the inputs, the rest of the error-detection tests can output to the proper directory
$out_seed_status_file = FileOpen($path_seed_status_file, 1+8 ) ; 1 = Write mode (append to end of file) ; 8 = Create directory structure if it doesn't exist
; logon_mon shouldn't try to start a new instance of quasi1d if one already exists
If (ProcessExists("quasi1d_many_scatterer" & $node_num & ".exe")<>0) Then
FileWrite($out_seed_status_file,"WARNING: quasi1d program already running when logon_mon launched" & @CRLF)
FileWrite($out_seed_status_file,"logon_mon exiting at " & _Now() & ". (quasi1d was not started)" & @CRLF)
FileClose($out_seed_status_file)
Exit
EndIf
; does the seed exist?
;Success: Returns 1.
;Failure: Returns 0 if path/file does not exist.
if (FileExists($seed_file)==0) Then
FileWrite($out_seed_status_file,"**************************************" & @CRLF)
FileWrite($out_seed_status_file,"WARNING: echo no seed file was in the specified research dump" & @CRLF)
FileWrite($out_seed_status_file,"logon_mon exiting " & _Now() & ". (quasi1d was not started)" & @CRLF)
FileClose($out_seed_status_file)
Exit
EndIf
; we start by assuming the seed file has a positive value
; 0 = Read mode
;FileOpen ($seed_file,0)
$chars = FileRead($seed_file) ; read the entire file, including @CRLF
;FileClose($seed_file)
;MsgBox(0,"seed",$chars)
; now we know the seed
; break the value into pieces
$seed=StringSplit($chars,"")
; $seed[0] is the number of elements in the arry
#cs
a note about the seed file: at minimum, the seed will be 2 characters (ie 43), the max will be 3 (ie 125).
The "find and replace" function is sensitive to whether the fourth character is a @CRlF since
the @CLRF can't be converted to a string. Need to convert tabs and crlf to a space
#ce
if ($seed[3]==@crlf) or ($seed[3]==@cr) or ($seed[3]==@TAB) Then
$seed[3]=" "
; this doesn't seem to work, so for now the seeds will need to have spaces after them
EndIf
; middle argument, "" is the delimiter. last two arguments are start and end array values
$positive_seed = _ArrayToString($seed, "",1,3) ; seeds like "23" or "139"
$negative_seed = "-" & $positive_seed
#cs
many ways to do many things:
-the commands in the Run(@comspec & "/c ") could be done in external batch files
-@computername is an autoit macro, whereas %computername% is a windows environment variable. [Equivilent]
-same for _Now() and %time%, %date% respectively
-setting priority can be done in autoIt using ProcessSetPriority() and in CLI using start /belownormal
#ce
if ($seed[1]=="-") Then ; seed is initially negative: BAD
Run(@COMSPEC & " /c echo ************************************** >> " & $path_seed_status_file)
Sleep(200)
Run(@COMSPEC & " /c echo Warning: initial seed has been detected to be negative (that's BAD) >> " & $path_seed_status_file)
Sleep(200)
Run(@COMSPEC & " /c echo Incorrect setup, or crash detection: computer may have been rebooted while program was running. >> " & $path_seed_status_file)
Sleep(200)
Run(@ComSpec & " /c echo Erasing all existing output data and starting over at " & _Now() & " >> " & $path_seed_status_file)
; logon_mon erases all output data (*.dat) and resets the input file to original
; version because the output data from the quasi1d exectuable should be treated as "corrupt"
; also, if the seed was simply misconfigured on the first run, no harm is done
FileDelete($researchdump & "*.dat")
$original_input_file = FileOpen ( $researchdump & "quasi1d_many_scatterer_parameters.input.original", 0 ) ; read-only mode
If $original_input_file = -1 Then
Run(@COMSPEC & " /c echo ************************************** >> " & $path_seed_status_file)
Sleep(200)
Run(@COMSPEC & " /c echo ERROR: cannot open quasi1d_many_scatterer_parameters.input.original >> " & $path_seed_status_file)
Exit
EndIf
FileClose($original_input_file)
$first_line_parameters = FileReadLine($original_input_file) ; read the first line only to get the original backup copy of parameters
$new_input_file = FileOpen($researchdump & "quasi1d_many_scatterer_parameters.input", 2 ) ; Write mode (erase previous contents)
FileWriteLine($new_input_file, $first_line_parameters & @CRLF & @CRLF) ; note: Fortran likes to have multiple lines in the input file (needs the CLRF)
FileClose($new_input_file)
; switch seed to postive, which so that logon_mon can continue
$retval = _ReplaceStringInFile($seed_file,$negative_seed,$positive_seed) ; (filename,find,replace)
ElseIf ($seed[1]=="1") OR ($seed[1]=="2") OR ($seed[1]=="3") OR ($seed[1]=="4") OR ($seed[1]=="5") OR ($seed[1]=="6") OR ($seed[1]=="7") OR ($seed[1]=="8") OR ($seed[1]=="9") Then ; seed is positive: GOOD
Run(@COMSPEC & " /c echo ************************************** >> " & $path_seed_status_file)
Sleep(200)
Run(@COMSPEC & " /c echo initial seed value detected to be positive (that's GOOD) >> " & $path_seed_status_file)
Sleep(200)
Run(@COMSPEC & " /c echo either this is the first run OR the computer may have been rebooted. If rebooted, program was NOT running at the time of reboot >> " & $path_seed_status_file)
Sleep(200)
Run(@ComSpec & " /c echo continuing logon_mon at " & _Now() & " >> " & $path_seed_status_file)
; going to continue on by resetting seed to negative
Else
Run(@COMSPEC & " /c echo ************************************** >> " & $path_seed_status_file)
Sleep(200)
Run(@COMSPEC & " /c echo initial seed value detected to be non-numeric (that's BAD) >> " & $path_seed_status_file)
Sleep(200)
Run(@ComSpec & " /c echo Exiting logon_mon at " & _Now() & " >> " & $path_seed_status_file)
Exit
endif
;MsgBox(0,"pos seed",$positive_seed)
;MsgBox(0,"neg seed",$negative_seed)
;Run(@COMSPEC & " /c echo and I got here, " & $negative_seed & " >> C:\researchdump1\actions.log")
;Run(@COMSPEC & " /c echo and I got here, " & $negative_seed & " >> C:\researchdump1\actions.log")
; wait until the screensaver exists to continue
ProcessWait($screensaver)
While 1 ; infinite loop
;Run(@COMSPEC & " /c echo and I got in the loop >> C:\researchdump1\actions.log")
; Success: Returns the PID of the process.
; Failure: Returns 0 if process does not exist.
If (ProcessExists($screensaver)>0) Then ; no one is logged on since screensaver is running. This ignores remote desktop sessions
; to resume the program the seed needs to be negative
; (file, find, replace)
$retval = _ReplaceStringInFile($seed_file,$positive_seed,$negative_seed)
if $retval = -1 then
Run(@COMSPEC & " /c ********************************* >> " & $path_seed_status_file)
Sleep(200)
Run(@COMSPEC & " /c seed was supposed to be flipped from positive to negative, but the positive seed value as not found >> " & $path_seed_status_file)
exit
else
Run(@COMSPEC & " /c ********************************* >> " & $path_seed_status_file)
Sleep(200)
Run(@COMSPEC & " /c seed was flipped from positive to negative >> " & $path_seed_status_file)
endif
;Run(@COMSPEC & " /c echo seed should be negative before program starts >> C:\researchdump1\actions.log")
Run(@COMSPEC & " /c echo step 1 - RESUMING/STARTING at " & _Now() & " >> " & $path_seed_status_file)
Sleep(200)
; run the program
Run(@COMSPEC & " /c start /belownormal /b " & $researchdump & "\" & $pausable_program_name & " >> output_%computername%_" & $node_num & ".dat",$researchdump)
; capture what is sent to the screen, specify environment path
; could have used AutoIt's ProcessSetPriority ( "process", priority)
; NOTE: IF THE PROGRAM CRASHES HERE THE SEED REMAINS NEGATIVE. Negative seeds with no program running thus indicate the run was interrupted.
Sleep(3000) ; wait three seconds to start the executable
; if the executable doesn't exist after it is started it probably completed previously
If (ProcessExists($pausable_program_name)==0) Then ; the program wasn't running, it must have finished
;MsgBox(0,"done","program finished")
Run(@COMSPEC & " /c echo DONE q1d.exe did not start at " & _Now() & ". Assuming the program previously finished. Time to RAR files >> " & path_seed_status_file)
Sleep(200)
Run(@COMSPEC & " /c local_renamer.cmd " & $node_num,$researchdump)
Exit ; quit logon_mon
Else
ProcessWaitClose($screensaver) ; when the screen saver closes, it means someone logged on
; need to include this so that the next step doesn't get immediately processed.
EndIf
;Run(@COMSPEC & " /c echo screensaver closed >> C:\researchdump1\actions.log")
EndIf
If (ProcessExists($screensaver)==0) Then ; the screen saver doesn't exist, someone is logged on: now we pause the running fortran program
;Run(@COMSPEC & " /c echo screen saver doesn't exist >> C:\researchdump1\actions.log")
; switch seed to postive, which pauses the fortran program
; (filename,find,replace)
$retval = _ReplaceStringInFile($seed_file,$negative_seed,$positive_seed)
if $retval = -1 then
Run(@COMSPEC & " /c ********************************* >> " & $path_seed_status_file)
Sleep(200)
Run(@COMSPEC & " /c seed was supposed to be flipped from negative to positive, but the negative seed value as not found >> " & $path_seed_status_file)
exit
else
Run(@COMSPEC & " /c ********************************* >> " & $path_seed_status_file)
Sleep(200)
Run(@COMSPEC & " /c seed was flipped from negative to positive >> " & $path_seed_status_file)
endif
Run(@COMSPEC & " /c echo step 2 - PAUSING switched seed to " & $positive_seed & " positive, waiting for q1d.exe to end >> " & $path_seed_status_file)
; if the executable doesn't exist as soon as the seed is switched to positive, it's probably because the program wasn't running. Thus it must have finished
If (ProcessExists($pausable_program_name)==0) Then ; the program wasn't running, it must have finished
;MsgBox(0,"done","program finished")
Run(@COMSPEC & " /c echo 0 DONE q1d.exe was not running when seed was switched. Time to RAR files >> " & $path_seed_status_file)
; switch seed back to negative
$retval = _ReplaceStringInFile($seed_file,$positive_seed,$negative_seed)
if $retval = -1 then
Run(@COMSPEC & " /c ********************************* >> " & $path_seed_status_file)
Sleep(200)
Run(@COMSPEC & " /c seed was supposed to be flipped from positive to negative, but the positive seed value as not found >> " & $path_seed_status_file)
exit
else
Run(@COMSPEC & " /c ********************************* >> " & $path_seed_status_file)
Sleep(200)
Run(@COMSPEC & " /c seed was flipped from positive to negative >> " & $path_seed_status_file)
endif
Run(@COMSPEC & " /c local_renamer.cmd " & $node_num,$researchdump)
Exit ; quit logon_mon
Else
ProcessWaitClose($pausable_program_name)
Run(@COMSPEC & " /c echo step 3 - PAUSED q1d.exe closed cleanly. Back to waiting for screen saver >> " & $path_seed_status_file)
EndIf
; wait for the screen saver to come back on, signifying box is not in use
ProcessWait($screensaver)
EndIf
; half-second pause so that the infinite loop isn't "tight", although the "processwaitclose" and "processwait" mean the loop doesn't run tight
; Sleep(500)
WEnd
#cs
Func TogglePause()
$Paused = NOT $Paused
While $Paused
sleep(100)
;ToolTip('Script is "Paused"',0,0)
WEnd
ToolTip("")
EndFunc
#ce
Func Terminate()
; Cleanly stop the logon_mon process.
;set seed to positive before exiting so that quasi1d can be restarted in the future
; (filename,find,replace)
$retval = _ReplaceStringInFile($seed_file,$negative_seed,$positive_seed)
Exit 0
EndFunc
; eof