WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Run Winbatch as a Service

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

UDF to Run Native Winbatch Service

Keywords: 	 Native Winbatch Service 

Here is a script that allows a script to run as a service but using Winbatch to manage the service rather than svrany.exe.

There can be problems with both ways. With svrany with you stop the service it just kills the application, with this it allows you to shut down yourlself. But with this you have to make sure you do keep track of what the servce has been told to do yourself.

I have included the UDF's (based off the example in the tech batabase) and a demo app (that does nothing).


; Name: Demo.wbt
; Description: Demo Winbatch Service script
; Comments:
; *** Please update the Version number each time you change this script
; The version is Major.Minor.Test

GoSub Init

; Loop forever
While 1
; check to see if the service has been paused, if so we should not do anything.
If !Pasued Then
;Here is where you can do what ever you want
EndIf
;Check to see if anything is happening to the service
Service_Message_Check()
EndWhile
Exit

;******************************************
;********* System Initilation **********
;******************************************
:Init

; Include other wbt files
#Include "Inc_Service.wbt"

If Param0 > 0 Then
; If '--debug' is passed in then log all all commands to a log file
If StrLower(Param1) == "--debug" Then
tracefile = StrCat(Path,"\debug.log")
If FileExist(tracefile)
FileDelete(tracefile)
EndIf
DebugTrace(@ON,tracefile)
EndIf
; If '--install' is passed in then Install the program as a service. The account that the service runs as will need to be changed once installed.
If StrLower(Param1) == "--install" Then
ret = Install_Service("WbtDemo","Winbatch Service Demo", "C:\temp\demo.exe")
; Check to see if the service was installed correctly
If ret <> 0 Then
Message("Error!","Error while creating service. Error Number: %Ret%")
Else
Message("Service Created","Please rename demo.exe to Demo.exs now. And change the account for the service.")
EndIf
; Quit application
Exit
EndIf
End If
; Go and configure the program to run as a service
Service_Init ()
Return











; Name: Inc_Service.wbt
; Description: Code to allow winbatch to run as a Service
; Comments:

;*******************************************************************************************
;**Install_Service: Function to install SysCheck as a Service **
;** Requires: **
;** Returns: int - 0 on success or the error number on fail. **
;** Comments: Once the service is installed the Account name will have to be changed **
;** as LocalSystem does not have much network access. **
;*******************************************************************************************
#DefineFunction Install_Service(ServiceName,DisplayName,BinaryPathName)
LoadOrderGroup = ""
AccountName = "LocalSystem"
Password = ""
createstring = StrCat(ServiceName,"|",DisplayName,"|",BinaryPathName,"|",LoadOrderGroup,"|",AccountName,"|",Password)
ServiceType = 256|16
StartType = 3
ErrorControl = 0
createflags = StrCat(ServiceType,"|",StartType,"|",ErrorControl)
mode = ErrorMode(@OFF)
LastError()
wntSvcCreate("", createstring, createflags, "","")
ErrorMode(mode)
Return LastError()
#EndFunction

;*******************************************************************************************
;**Service_Init: Set the appliction to run as a service **
;** Requires: **
;** Returns: **
;** Comments: This checks to see if it is running as a service, if so tells Windows **
;** what service commands it will accept. **
;*******************************************************************************************
#DefineSubRoutine Service_Init ()
SERVICE_ACCEPT_STOP = 1 ;The service can be stopped
SERVICE_ACCEPT_PAUSE_CONTINUE = 2 ;The service can be paused and continued
SERVICE_ACCEPT_SHUTDOWN = 4 ;The service is notified when system shutdown occurs
SERVICE_ACCEPT_LOGOFF = 32768;The service is notified when user logoff occurs
;Initialize variables for the SvcSetState function
SERVICE_STATE_STOPPED = 1 ;The service is not running
SERVICE_STATE_STOP_PENDING = 3 ;The service is stopping
SERVICE_STATE_RUNNING = 4 ;The service is running
SERVICE_STATE_CONTINUE_PENDING = 5 ;The service continue is pending
SERVICE_STATE_PAUSE_PENDING = 6 ;The service pause is pending
SERVICE_STATE_PAUSED = 7 ;The service is paused
;Initialize variables for the SvcWaitForCmd function
SERVICE_CONTROL_NOT_SERVICE = -1 ;Script not running as a service
SERVICE_CONTROL_TIMEOUT = 0 ;Timeout occurred or no codes to process
SERVICE_CONTROL_STOP = 1 ;Requests the service to stop
SERVICE_CONTROL_PAUSE = 2 ;Requests the service to pause
SERVICE_CONTROL_CONTINUE = 3 ;Requests the paused service to resume
SERVICE_CONTROL_SHUTDOWN = 5 ;Requests the service to perform
SERVICE_CONTROL_USER128 = 128 ;User command 128
SERVICE_CONTROL_USER129 = 129 ;User command 129
SERVICE_CONTROL_USER130 = 130 ;User command 130
SERVICE_CONTROL_USER131 = 131 ;User command 131
; ;More user commands as needed
SERVICE_CONTROL_USER255 = 255 ;User command 255
SERVICE_CONTROL_LOGOFF = 32768 ;logoff notification
; Default paused state to false
Paused = @FALSE
; Setup debugging prompt strings.... (used when not running as a service to test service code)
debugcodes="0: Timeout|1: Stop|2: Pause|3: Continue|5: Shutdown|128: User Cmd 128|129:User Cmd 129|32768: Logoff"
; Tell Windows what service commands this application will accept
flag=SvcSetAccept( SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_LOGOFF )
; Test to see if the program is running as a service or not
If !(flag == -1) Then
; Running as a service, so set up error handling
; Tell WinBatch to not honor terminate and not complain on Windows exit
IntControl(12,2+8,0,0,0)
IntControl(38,1,"%Path%errorlog.txt",0,0) ;Route fatal errors to a log file
DoingDebug=@FALSE
Else
; Not running as a service, so change path and turn on debug mode
DoingDebug=@TRUE
Path = "c:\temp"
EndIf
Return
#EndSubRoutine

;*******************************************************************************************
;**Service_Message_Check: Check for service messages and act on them **
;** Requires: **
;** Returns: **
;** Comments: Waits for the set Delay time for a service control message **
;*******************************************************************************************
#DefineSubRoutine Service_Message_Check ()
pasued = @FALSE
If DoingDebug==@FALSE
; this is running as a service so wait for delay time to see if there are any messages
code=SvcWaitForCmd(loop_Delay*1000)
Else
; Not running as a service, prompt tester to see what code should be pretended here
code=AskItemlist("Service Debug",debugcodes,"|",@UNSORTED,@SINGLE)
If code=="" Then Continue
code=ItemExtract(1,code,":")
EndIf
Switch code
Case SERVICE_CONTROL_TIMEOUT
;Timeout occurred
BoxText("TimeoutOccured")
Break
Case SERVICE_CONTROL_STOP
;Stop command received
BoxText("Stop command received")
SvcSetState(SERVICE_STATE_STOP_PENDING)
;do stop cleanup work here
SvcSetState(SERVICE_STATE_STOPPED)
Exit ;Goodbye
Break
Case SERVICE_CONTROL_PAUSE
;Pause command received
BoxText("Pause command received")
SvcSetState(SERVICE_STATE_PAUSE_PENDING)
;do pause cleanup work here
Paused = @TRUE
SvcSetState(SERVICE_STATE_PAUSED)
Break
Case SERVICE_CONTROL_CONTINUE
;Continue command received
BoxText("Continue command received")
SvcSetState(SERVICE_STATE_CONTINUE_PENDING)
;do resume from pause state initilization here
Paused = @FALSE
SvcSetState(SERVICE_STATE_RUNNING)
Break
Case SERVICE_CONTROL_SHUTDOWN
;Shutdown notification received
;Approx. 20 seconds to process
BoxText("Shutdown notification received")
SvcSetState(SERVICE_STATE_STOP_PENDING)
;do stop cleanup work here
SvcSetState(SERVICE_STATE_STOPPED)
Exit ;Goodbye
Break
Case SERVICE_CONTROL_USER128
;User command 128 received
BoxText("User command 128 received")
Break
Case SERVICE_CONTROL_USER129
;User command 129 received
BoxText("User command 129 received")
Break
Case SERVICE_CONTROL_LOGOFF
;Logoff command received
BoxText("Logoff command received")
Break
Case code
;Unrecognized command received
BoxText("Unrecognized command received")
Break
EndSwitch
Return
#EndSubRoutine




Article ID:   W15685
File Created: 2005:10:19:08:59:04
Last Updated: 2005:10:19:08:59:04