Break On
; Example code to run a script as a service with the following features:
; * Manager process insures that the dispatch process keeps running
; * Manager process is controlled as a service by SrvAny.exe
; * Manager is invoked when the script is called without a $PID argument
; * Dispatcher process invokes a Processor to run specific tasks
; * Dispatcher runs in an infinite loop, tracks the PID of the manager
; and terminates if the Manager process terminates.
; * Dispatcher checks for a new version of the script and copies/exits for
; a self-updating feature. The Manager then restarts using the new script
; * Processor has a $PID of 0 and $ARG defining the specific task to perform
; * Processor performs the task and exits
; * Processor is invoked via RUN to run independently, allowing many Procesor
; events to occur. The code can limit the number of similar Processor tasks
; by tracking the PIDs.
Dim $Rc
; Set desired program options - NoVarsInStrings is required
$Rc = SetOption('NoVarsInStrings', 'On')
$Rc = SetOption('Explicit', 'On')
; If $PID is not specified, run as a front-end process
If Not IsDeclared($PID)
Global $PID
'Service front-end started. PID=' @PID ?
; Loop forever until terminated by external triggger (Service stop)
; no application-specific initialization is required.
; run the script with a PID arg so it runs as the back-end dispatcher
; It will terminate itself if the front-end PID dies. It can also
; terminate due to finding a newer version - it will self-update and exit,
; and this front-end will restart it.
While 1
Shell '%COMSPEC% /c Kix32.exe ' + @SCRIPTNAME + ' $PID=' + @PID
Loop
EndIf
; perform application initialization common to the Dispatch service and all Processor sub-tasks
Dim $A ; random arg value
Dim $I ; counter
'common init' ?
SRnd(@TICKS)
; if $ARG is declared, then this is a PROCESSOR sub-task running independent of the service
; Run the specific task and exit.
If IsDeclared($ARG)
; Use a Select/Case to decide what to do
; for now, pretend we're doing something useful...
'Specific subtask: ' $ARG ?
Sleep 5
Exit 0
EndIf
; This is the service back-end, which performs additional init, overall management, and
; scheduled dispatching of sub-tasks. It monitors the front-end process PID and terminates
; if it dies. It also checks for a newer version, copies it over the current version and
; exits. The front-end service will restart this, using the new code.
'Starting service back-end. PID=' @PID ?
$I = 0
While 1 ; start of main service loop
; insure that our parent process is running - we die if it isn't
$Rc = WmiProcessList($PID)
If @ERROR 'Terminate' ? Exit 0 EndIf
; test for service code update
If Exist(@SCRIPTDIR + '\service.new')
If Exist(@SCRIPTDIR + '\service.old')
Del @SCRIPTDIR + '\service.old'
EndIf
Move @SCRIPTDIR + '\service.kix' @SCRIPTDIR + '\service.old'
Move @SCRIPTDIR + '\service.new' @SCRIPTDIR + '\service.kix'
'Updated!' ?
Exit 0
EndIf
; Identify who we are
; change this to "version 2" and save as "service.new" to test the auto-update feature
'Version 1' ?
Sleep 0.5 ; pretend we're doing serious work here...
$I = $I + 1
; trigger a sub-task - would normally be done on a timer of some sort, with different
; Processor events occurring at different times. For now, just provide a random character
; as the $ARG argument
If $I = 20 ; run a subtask every 10 secondss
$I = 0
$A = Int(Rnd(8)) + 1
Run '%COMSPEC% /c wKix32.exe ' + @SCRIPTNAME + ' $PID=' + 0 + ' $ARG="' + Chr(64 + $A) + '"'
EndIf
Loop ; end of main service loop