;created By arcker, for autoit community ;modified by synapse v.17.07.17 (beta) #include-once #include "WinAPI.au3" #include "ServicesConstants.au3" #include "File.au3" ;required for logging only ; Globals for Au3@service routines ; Enable Debugging messages Dim $bAU3ServiceDebug = True Dim $hAdvapi32_DLL = DllOpen("Advapi32.dll") Dim $hKernel32_DLL = DllOpen("kernel32.dll") Dim $sServiceName = "Autoit_Service" Dim $bServiceRunning = False Dim $tServiceName,$tServiceCtrl,$tServiceMain Dim $tService_Status = DllStructCreate("dword dwServiceType;" & _ "dword dwCurrentState;dword dwControlsAccepted;dword dwWin32ExitCode;" & _ "dword dwServiceSpecificExitCode;dword dwCheckPoint;dword dwWaitHint") Dim $hService_Status_handle = 0 ; #INDEX# ========================================================================================================================================================== ; Title .........: Services ; AutoIt Version : 3.2.10++ ; Language ......: English ; Description ...: Windows service management for AutoIt, with AutoIt-as-service functionality. ; Authors .......: Engine, Arcker ; ...............: Shminkyboy, udgeen ; ================================================================================================================================================================== ; #FUNCTION# ======================================================================================================================================================= ; Name...........: _Service_Create ; Description ...: Creates a service. ; Syntax.........: _Service_Create($sServiceName, $sDisplayName, $iServiceType, $iStartType, $iErrorControl, $sBinaryPath _ ; [, $sLoadOrderGroup, $fTagId, $vDependencies, $sServiceUser, $sPassword, $sComputerName]) ; Parameters ....: $sServiceName - Name of the service. ; $sDisplayName - The display name to be used by user interface programs to identify the service. The maximum string length is 256 characters. ; The service control manager database preserves the case of the characters, ; but service name comparisons are always case insensitive. ; Forward-slash (/) and back-slash (\) are invalid service name characters. ; $iServiceType - The type of service. Specify one of the following service types: ; $SERVICE_KERNEL_DRIVER - Driver service. ; $SERVICE_FILE_SYSTEM_DRIVER - File system driver service. ; $SERVICE_WIN32_OWN_PROCESS - Service that runs in its own process. ; $SERVICE_WIN32_SHARE_PROCESS - Service that shares a process with other services. ; If you specify either $SERVICE_WIN32_OWN_PROCESS or $SERVICE_WIN32_SHARE_PROCESS, ; and the service is running in the context of the LocalSystem account, you can also specify the following type: ; $SERVICE_INTERACTIVE_PROCESS - The service can interact with the desktop. ; $iStartType - The service start options. Specify one of the following start types: ; $SERVICE_BOOT_START - A device driver started by the system loader. This value is valid only for driver services. ; $SERVICE_SYSTEM_START - A device driver started by the IoInitSystem function. This value is valid only for driver services. ; $SERVICE_AUTO_START - A service started automatically by the service control manager during system startup. ; $SERVICE_DEMAND_START - A service started by the service control manager when a process calls the StartService function. ; $SERVICE_DISABLED - A service that cannot be started. ; $iErrorControl - The severity of the error, and action taken, if this service fails to start. Specify one of the following values: ; $SERVICE_ERROR_IGNORE - The startup program ignores the error and continues the startup operation. ; $SERVICE_ERROR_NORMAL - The startup program logs the error in the event log but continues the startup operation. ; $SERVICE_ERROR_SEVERE - The startup program logs the error in the event log. ; If the last-known-good configuration is being started, the startup operation continues. ; Otherwise, the system is restarted with the last-known-good configuration. ; $SERVICE_ERROR_CRITICAL - The startup program logs the error in the event log, if possible. ; If the last-known-good configuration is being started, the startup operation fails. ; Otherwise, the system is restarted with the last-known good configuration. ; $sBinaryPath - The fully-qualified path to the service binary file. If the path contains a space, ; it must be quoted so that it is correctly interpreted. ; For example, "d:\\my share\\myservice.exe" should be specified as "\"d:\\my share\\myservice.exe\"". ; The path can also include arguments for an auto-start service. For example, "d:\\myshare\\myservice.exe arg1 arg2". ; These arguments are passed to the service entry point (typically the main function). ; $sLoadOrderGroup - [Optional] The name of the load ordering group of which this service is a member. ; Specify "Default" or an empty string if the service does not belong to a group. ; $fTagId - [Optional] Specify "True" if you desire a tag value that is unique in the group specified in the $sLoadOrderGroup parameter. ; Specify "False" or "Default" if you do not desire a tag value. ; The tag value is stored in @extended macro. ; You can use a tag for ordering service startup within a load ordering group by specifying a tag order vector in the ; GroupOrderList value of the following registry key: ; HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control ; Tags are only evaluated for driver services that have $SERVICE_BOOT_START or $SERVICE_SYSTEM_START start types. ; $vDependencies - [Optional] An array of services or load ordering groups that the system must start before this service can be started. ; (Dependency on a group means that this service can run if at least one member of the group is running after an attempt to ; start all members of the group.) Specify "Default" or an empty string if the service has no dependencies. ; You must prefix group names with a plus sign ("+") so that they can be distinguished from a service name, ; because services and service groups share the same name space. ; $sServiceUser - [Optional] The name of the account under which the service should run. ; If the service type is $SERVICE_WIN32_OWN_PROCESS, use an account name in the form DomainName\UserName. ; The service process will be logged on as this user. If the account belongs to the built-in domain, ; you can specify .\UserName . A shared process can run as any user. ; If the service type is $SERVICE_KERNEL_DRIVER or $SERVICE_FILE_SYSTEM_DRIVER, ; the name is the driver object name that the system uses to load the device driver. ; Specify "Default" if the driver is to use a default object name created by the I/O system. ; $sPassword - [Optional] The password to the account name specified by the $sServiceUser parameter. ; Specify "Default" or an empty string if the account has no password or if the service runs in the LocalService, NetworkService, ; or LocalSystem account. Passwords are ignored for driver services. ; $sComputerName - [Optional] The name of the target computer. The local computer is default. ; Requirement(s).: Administrative rights on the target computer. ; Return values .: Success - 1 ; Failure - 0 ; Sets @error ; Author ........: engine ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; ================================================================================================================================================================== Func _Service_Create($sServiceName, _ $sDisplayName, _ $iServiceType, _ $iStartType, _ $iErrorControl, _ $sBinaryPath, _ $sLoadOrderGroup = Default, _ $fTagId = Default, _ $vDependencies = Default, _ $sServiceUser = Default, _ $sPassword = Default, _ $sComputerName = "") Local $tLoadOrderGroup, $tTagId, $tDepend, $tServiceUser, $tPassword, $hSC, $avSC, $iSC $tLoadOrderGroup = DllStructCreate("wchar[" & Number($sLoadOrderGroup <> Default) * (StringLen($sLoadOrderGroup) + 1) & "]") DllStructSetData($tLoadOrderGroup, 1, $sLoadOrderGroup) $tTagId = DllStructCreate("dword[" & Number($fTagId) & "]") If IsArray($vDependencies) Then Local $iDepend, $tagDepend $iDepend = UBound($vDependencies) - 1 For $i = 0 To $iDepend $tagDepend &= "wchar[" & StringLen($vDependencies[$i]) + 1 & "];" Next $tDepend = DllStructCreate(StringTrimRight($tagDepend, 1)) For $i = 0 To $iDepend DllStructSetData($tDepend, $i + 1, $vDependencies[$i]) Next Else $tDepend = DllStructCreate("wchar[" & Number($vDependencies <> Default) * (StringLen($vDependencies) + 1) & "]") DllStructSetData($tDepend, 1, $vDependencies) EndIf $tServiceUser = DllStructCreate("wchar[" & Number($sServiceUser <> Default) * (StringLen($sServiceUser) + 1) & "]") DllStructSetData($tServiceUser, 1, $sServiceUser) $tPassword = DllStructCreate("wchar[" & Number($sPassword <> Default) * (StringLen($sPassword) + 1) & "]") DllStructSetData($tPassword, 1, $sPassword) $hSC = OpenSCManager($sComputerName, $SC_MANAGER_CREATE_SERVICE) $avSC = DllCall($hAdvapi32_DLL, "ptr", "CreateServiceW", _ "ptr", $hSC, _ "wstr", $sServiceName, _ "wstr", $sDisplayName, _ "dword", $SERVICE_ALL_ACCESS, _ "dword", $iServiceType, _ "dword", $iStartType, _ "dword", $iErrorControl, _ "wstr", $sBinaryPath, _ "ptr", DllStructGetPtr($tLoadOrderGroup), _ "ptr", DllStructGetPtr($tTagId), _ "ptr", DllStructGetPtr($tDepend), _ "ptr", DllStructGetPtr($tServiceUser), _ "ptr", DllStructGetPtr($tPassword)) If $avSC[0] = 0 Then $iSC = _WinAPI_GetLastError() Else CloseServiceHandle($avSC[0]) EndIf CloseServiceHandle($hSC) Return SetError($iSC, DllStructGetData($tTagId, 1), Number($avSC[0] <> 0)) EndFunc ;==>_Service_Create ; #FUNCTION# ======================================================================================================================================================= ; Name...........: _Service_Delete ; Description ...: Deletes a service. ; Syntax.........: _Service_Delete($sServiceName [, $sComputerName]) ; Parameters ....: $sServiceName - Name of the service. ; $sComputerName - [Optional] The name of the target computer. The local computer is default. ; Requirement(s).: Administrative rights on the target computer. ; Return values .: Success - 1 ; Failure - 0 ; Sets @error ; Author ........: engine ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; ================================================================================================================================================================== Func _Service_Delete($sServiceName, $sComputerName = "") Local $hSC, $hService, $avDS, $iDS $hSC = OpenSCManager($sComputerName, $SC_MANAGER_CONNECT) $hService = OpenService($hSC, $sServiceName, $DELETE) $avDS = DllCall($hAdvapi32_DLL, "int", "DeleteService", _ "ptr", $hService) If $avDS[0] = 0 Then $iDS = _WinAPI_GetLastError() CloseServiceHandle($hService) CloseServiceHandle($hSC) Return SetError($iDS, 0, $avDS[0]) EndFunc ;==>_Service_Delete ; #FUNCTION# ======================================================================================================================================================= ; Name...........: _Service_Exists ; Description ...: Checks if a service exists. ; Syntax.........: _Service_Exists($sServiceName [, $sComputerName]) ; Parameters ....: $sServiceName - Name of the service. ; $sComputerName - [Optional] The name of the target computer. The local computer is default. ; Requirement(s).: None. ; Return values .: Success - 1 ; Failure - 0 ; Author ........: engine ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; ================================================================================================================================================================== Func _Service_Exists($sServiceName, $sComputerName = "") Local $hSC, $hService $hSC = OpenSCManager($sComputerName, $SC_MANAGER_CONNECT) $hService = OpenService($hSC, $sServiceName, $SERVICE_INTERROGATE) CloseServiceHandle($hService) CloseServiceHandle($hSC) Return Number($hService <> 0) EndFunc ;==>_Service_Exists ; #FUNCTION# ======================================================================================================================================================= ; Name...........: _Service_QueryType ; Description ...: Retrieves a service's type. ; Syntax.........: _Service_QueryType($sServiceName [, $sComputerName]) ; Parameters ....: $sServiceName - Name of the service. ; $sComputerName - [Optional] The name of the target computer. The local computer is default. ; Requirement(s).: None. ; Return values .: Success - Returns the type of service. Can be one of the following values: ; $SERVICE_KERNEL_DRIVER - The service is a device driver. ; $SERVICE_FILE_SYSTEM_DRIVER - The service is a file system driver. ; $SERVICE_WIN32_OWN_PROCESS - The service runs in its own process. ; $SERVICE_WIN32_SHARE_PROCESS - The service shares a process with other services. ; BitOR($SERVICE_WIN32_OWN_PROCESS, $SERVICE_INTERACTIVE_PROCESS) - The service runs in its own process ; and can interact with the desktop. ; BitOR($SERVICE_WIN32_SHARE_PROCESS, $SERVICE_INTERACTIVE_PROCESS) - The service shares a process with other services ; and can interact with the desktop. ; Failure - 0 ; Sets @error ; Author ........: engine ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; ================================================================================================================================================================== Func _Service_QueryType($sServiceName, $sComputerName = "") Local $hSC, $hService, $avQA, $tQB, $avQB, $iQE, $tQC $hSC = OpenSCManager($sComputerName, $SC_MANAGER_CONNECT) $hService = OpenService($hSC, $sServiceName, $SERVICE_QUERY_CONFIG) ; Determine needed size of the struct in bytes $avQA = QueryServiceConfig($hService, 0, 0) ; Get Service data $tQB = DllStructCreate("ubyte[" & $avQA[4] & "]") $avQB = QueryServiceConfig($hService, DllStructGetPtr($tQB), DllStructGetSize($tQB)) ; Get last error and close service handle If $avQB[0] = 0 Then $iQE = _WinAPI_GetLastError() CloseServiceHandle($hService) CloseServiceHandle($hSC) ; Decode the ubyte structure $tQC = DllStructCreate("dword[3];uint_ptr[2];dword;uint_ptr[3]", $avQB[2]) Return SetError($iQE, 0, DllStructGetData($tQC, 1, 1)) EndFunc ;==>_Service_QueryType ; #FUNCTION# ======================================================================================================================================================= ; Name...........: _Service_Start ; Description ...: Starts a service. ; Syntax.........: _Service_Start($sServiceName [, $sComputerName]) ; Parameters ....: $sServiceName - Name of the service. ; $sComputerName - [Optional] The name of the target computer. The local computer is default. ; Requirement(s).: Administrative rights on the target computer. ; Return values .: Success - 1 ; Failure - 0 ; Sets @error ; Author ........: engine ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; ================================================================================================================================================================== Func _Service_Start($sServiceName, $sComputerName = "") Local $hSC, $hService, $avSS, $iSS $hSC = OpenSCManager($sComputerName, $SC_MANAGER_CONNECT) $hService = OpenService($hSC, $sServiceName, $SERVICE_START) $avSS = DllCall($hAdvapi32_DLL, "int", "StartServiceW", _ "ptr", $hService, _ "dword", 0, _ "ptr", 0) If $avSS[0] = 0 Then $iSS = _WinAPI_GetLastError() CloseServiceHandle($hService) CloseServiceHandle($hSC) Return SetError($iSS, 0, $avSS[0]) EndFunc ;==>_Service_Start ; #FUNCTION# ======================================================================================================================================================= ; Name...........: _Service_Stop ; Description ...: Stops a service. ; Syntax.........: _Service_Stop($sServiceName [, $sComputerName]) ; Parameters ....: $sServiceName - Name of the service. ; $sComputerName - [Optional] The name of the target computer. The local computer is default. ; Requirement(s).: Administrative rights on the target computer. ; Return values .: Success - 1 ; Failure - 0 ; Sets @error ; Author ........: engine ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; ================================================================================================================================================================== Func _Service_Stop($sServiceName, $sComputerName = "") Local $hSC, $hService, $iCSS, $iCSSE $hSC = OpenSCManager($sComputerName, $SC_MANAGER_CONNECT) $hService = OpenService($hSC, $sServiceName, $SERVICE_STOP) $iCSS = ControlService($hService, $SERVICE_CONTROL_STOP) If $iCSS = 0 Then $iCSSE = _WinAPI_GetLastError() CloseServiceHandle($hService) CloseServiceHandle($hSC) Return SetError($iCSSE, 0, $iCSS) EndFunc ;==>_Service_Stop Func CloseServiceHandle($hSCObject) Local $avCSH = DllCall($hAdvapi32_DLL, "int", "CloseServiceHandle", _ "ptr", $hSCObject) If @error Then Return SetError(@error, 0, 0) Return $avCSH[0] EndFunc ;==>CloseServiceHandle Func ControlService($hService, $iControl) Local $avCS = DllCall($hAdvapi32_DLL, "int", "ControlService", _ "ptr", $hService, _ "dword", $iControl, _ "ptr*", 0) If @error Then Return SetError(@error, 0, 0) Return $avCS[0] EndFunc ;==>ControlService Func OpenSCManager($sComputerName, $iAccess) Local $avOSCM = DllCall($hAdvapi32_DLL, "ptr", "OpenSCManagerW", _ "wstr", $sComputerName, _ "wstr", $SERVICES_ACTIVE_DATABASE, _ "dword", $iAccess) If @error Then Return SetError(@error, 0, 0) Return $avOSCM[0] EndFunc ;==>OpenSCManager Func OpenService($hSC, $sServiceName, $iAccess) Local $avOS = DllCall($hAdvapi32_DLL, "ptr", "OpenServiceW", _ "ptr", $hSC, _ "wstr", $sServiceName, _ "dword", $iAccess) If @error Then Return SetError(@error, 0, 0) Return $avOS[0] EndFunc ;==>OpenService Func QueryServiceConfig($hService, $pServiceConfig, $iBufSize) Local $avQSC = DllCall($hAdvapi32_DLL, "int", "QueryServiceConfigW", _ "ptr", $hService, _ "ptr", $pServiceConfig, _ "dword", $iBufSize, _ "dword*", 0) Return $avQSC EndFunc ;==>QueryServiceConfig ;~ Au3@Service routines by 'Arcker'. Modified by ShminkyBoy to include support for interactive services ;/*--------------------------[ _Service_ServiceInit ]--------------------------------- ; * Init service, register callback service functions and StartServiceCtrlDispatcher ; * ; * Parameters: ; * sServiceName - Service Name ; * ; * ; * ; * Return value: ; * non zero - success ; * zero - failure ; *----------------------------------------------------------------------------------*/ Func _Service_Init($sServiceName) Local $result; If $bAU3ServiceDebug Then logprint("_Service_Init(" & $sServiceName & ")") ; Register CallBacks for RegisterServiceCtrlHandlerEx Function $tServiceCtrl = DllCallbackRegister("_Service_Ctrl", "dword", "dword;dword;ptr;ptr") $tServiceMain = DllCallbackRegister("_Service_ServiceMain", "none", "dword;ptr") Local $tagSERVICE_TABLE_ENTRY = "STRUCT;ptr lpServiceName;ptr lpServiceProc;ENDSTRUCT" ;We create array with two struct because the members of the last entry in the table must have NULL values to designate the end of the table. Local $tdispatchTable = DllStructCreate($tagSERVICE_TABLE_ENTRY & ";" & $tagSERVICE_TABLE_ENTRY) $tServiceName = DllStructCreate("char["&StringLen($sServiceName)&"]") DllStructSetData($tdispatchTable, 1, DllStructGetPtr($tServiceName)) DllStructSetData($tdispatchTable, 2, DllCallbackGetPtr($tServiceMain)) ;BOOL WINAPI StartServiceCtrlDispatcher(_In_ const SERVICE_TABLE_ENTRY *lpServiceTable); ;typedef struct _SERVICE_TABLE_ENTRY { ; LPTSTR lpServiceName; <- Service Name ; LPSERVICE_MAIN_FUNCTION lpServiceProc; <- Service Main Function ;} SERVICE_TABLE_ENTRY, *LPSERVICE_TABLE_ENTRY; $result=DllCall($hAdvapi32_DLL, "int", "StartServiceCtrlDispatcher", "ptr", DllStructGetPtr($tdispatchTable)) ;cleanup a little $tServiceName = 0 $tdispatchTable = 0 If $result[0]=0 Then logprint("Service _Service_init() error " & @error & " - " & _WinAPI_GetLastErrorMessage()) Exit EndIf return $result[0] EndFunc ;==>_Service_init ;/*--------------------------[ _Service_ServiceMain ]-------------------------- ; * Register service, start and stop running service payload in loop ; * ; * Parameters: ; * iArg - The number of arguments in the pArgs array ; * pArgs - The null-terminated argument strings passed to the service by the call to the StartService function that started the service. ;* If there are no arguments, this parameter can be NULL. Otherwise, the first argument (lpszArgv[0]) is the name of the service, ;* followed by any additional arguments (pArgs[1] through pArgs[iArg-1]). ;* If the user starts a manual service using the Services snap-in from the Control Panel, the strings for the pArgs parameter ;* come from the properties dialog box for the service (from the Services snap-in, right-click the service entry, click Properties, ;* and enter the parameters in Start parameters.) ; * ; * ; * Return value: ; * none ; * ; *----------------------------------------------------------------------------*/ Func _Service_ServiceMain($iArg, $pArgs) ;register service Local $result = DllCall($hAdvapi32_DLL, "ptr", "RegisterServiceCtrlHandlerEx", "ptr", DllStructGetPtr($tServiceName), "ptr", DllCallbackGetPtr($tServiceCtrl),"ptr",0) $hService_Status_handle = $result[0] If $hService_Status_handle = 0 Then if $bAU3ServiceDebug then logprint("Error Call RegisterServiceCtrlHandlerEx() - " & _WinAPI_GetLastError()) Exit Else if $bAU3ServiceDebug then logprint("Service succefully registered via RegisterServiceCtrlHandlerEx()") DllStructSetData($tService_Status, "dwServiceType", _Service_QueryType($sServiceName)) DllStructSetData($tService_Status, "dwServiceSpecificExitCode", 0); ; report the status to the service control manager. _Service_ReportStatus($SERVICE_START_PENDING, $NO_ERROR, 0) if $bAU3ServiceDebug then logprint("Service succefully report status SERVICE_START_PENDING via SetServiceStatus()") _Service_ReportStatus($SERVICE_RUNNING, $NO_ERROR, 0) if $bAU3ServiceDebug then logprint("Service succefully report status SERVICE_RUNNING via SetServiceStatus()") $bServiceRunning = True if $bAU3ServiceDebug then logprint("Service start payload loop") While $bServiceRunning _Service_payload($iArg, $pArgs) WEnd _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, 1000) if $bAU3ServiceDebug then logprint("Service succefully report status SERVICE_STOP_PENDING via SetServiceStatus()") DllCallbackFree($tServiceMain) DllCallbackFree($tServiceCtrl) if $bAU3ServiceDebug then logprint("Service freeing resources") _Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0) if $bAU3ServiceDebug then logprint("Service succefully report status SERVICE_STOPPED via SetServiceStatus()") DllClose($hAdvapi32_DLL) DllClose($hKernel32_DLL) if $bAU3ServiceDebug then logprint("Service closed DLLS") EndIf EndFunc ;==>_Service_ServiceMain ;/*--------------------------[ _Service_ReportStatus ]-------------------------- ; * Sets the current status and reports it to the Service Control Manager ; * ; * Parameters: ; * currentState - the state of the service ; * exitCode - error code to report ; * waitHint - worst case estimate to next checkpoint ; * ; * Return value: ; * non zero - success ; * zero - failure ; *----------------------------------------------------------------------------*/ Func _Service_ReportStatus($currentState, $exitCode, $waitHint) Static $gdwCheckPoint = 1 If $bAU3ServiceDebug Then logprint("Service _Service_ReportStatus() received status = " & $currentState ) If ($currentState = $SERVICE_START_PENDING) Then DllStructSetData($tService_Status, "dwControlsAccepted", 0) Else DllStructSetData($tService_Status, "dwControlsAccepted", BitOR($SERVICE_ACCEPT_STOP, $SERVICE_ACCEPT_SHUTDOWN)) EndIf DllStructSetData($tService_Status, "dwCurrentState", $currentState) DllStructSetData($tService_Status, "dwWin32ExitCode", $exitCode) DllStructSetData($tService_Status, "dwWaitHint", $waitHint) If ($currentState = $SERVICE_RUNNING) Or ($currentState = $SERVICE_STOPPED) Then DllStructSetData($tService_Status, "dwCheckPoint", 0) Else $gdwCheckPoint += 1 If $bAU3ServiceDebug Then logprint("dwCheckPoint => " & $gdwCheckPoint & @crlf) DllStructSetData($tService_Status, "dwCheckPoint", $gdwCheckPoint) EndIf Local $result = DllCall($hAdvapi32_DLL, "int", "SetServiceStatus", "handle", $hService_Status_handle, "ptr", DllStructGetPtr($tService_Status)) If $result[0]=0 Then If $bAU3ServiceDebug Then logprint("Service SetServiceStatus() Error " & @error & " - " & _WinAPI_GetLastError()) Exit EndIf Return $result[0] EndFunc ;==>_Service_ReportStatus ;/*------------------------------[ service_ctrl ]------------------------------ ; * Called by the SCM whenever ControlService() is called for this service ; * ; * Parameters: ; * ctrlCode - type of control requested ; * ; * Return value: ; * none ; *----------------------------------------------------------------------------*/ Func _Service_Ctrl($dwControl, $dwEventType, $lpEventData, $lpContext) ;handler ex Switch $dwControl Case $SERVICE_CONTROL_STOP,$SERVICE_ACCEPT_SHUTDOWN ; new in v4, stop when system shutdown ( better mmm ? ) $bServiceRunning = False Return $NO_ERROR Case $SERVICE_CONTROL_PAUSE DllStructSetData($tService_Status, "dwCurrentState", $SERVICE_PAUSED) Case $SERVICE_CONTROL_CONTINUE DllStructSetData($tService_Status, "dwCurrentState", $SERVICE_RUNNING) Case $SERVICE_CONTROL_INTERROGATE Return $NO_ERROR Case $SERVICE_CONTROL_SESSIONCHANGE Case 128 To 255 ; custom messages ; handle custom messages Case Else ; invalid or unhandled control code ;~ $return = $ERROR_CALL_NOT_IMPLEMENTED EndSwitch Return $NO_ERROR EndFunc ;==>_Service_Ctrl ;/*------------------------------[ logprint ]------------------------------ ; * Log debug messages to file ; * ; * Parameters: ; * logmsg - log message ; * logfile - log file path ; * exitafter - exit after write log message flag ; * ; * Return value: ; * none ; *----------------------------------------------------------------------------*/ Func logprint($logmsg,$logfile=@ScriptDir & "\" & @ScriptName &".log", $exitafter=0) _FileWriteLog($logfile, $logmsg) if ($exitafter==1) Then Exit EndFunc