;-- TIME_STAMP 2022-01-24 11:21:16 ; #GLOBALS# ===================================================================================================================== Global Enum Step *2 _ $SSM_Boot, $SSM_System, $SSM_Auto, $SSM_Manual, $SSM_Disabled, _ ; SSM = [S]ervice-[S]tart-[M]ode $SST_Stopped, $SST_StartPending, $SST_StopPending, $SST_Running, $SST_ContinuePending, $SST_PausePending, $SST_Paused, $SST_Unknown, _ ; SST = [S]ervice-[ST]ate $SSS_OK, $SSS_Error, $SSS_Degraded, $SSS_Unknown, $SSS_PredFail, $SSS_Starting, $SSS_Stopping, $SSS_Service ; SSS = [S]ervice-[S]tatu[S] ; Service Type Global Const $KERNEL_DRIVER = 0x1 Global Const $FILE_SYSTEM_DRIVER = 0x2 Global Const $ADAPTER = 0x4 Global Const $RECOGNIZER_DRIVER = 0x8 Global Const $OWN_PROCESS = 0x10 Global Const $SHARE_PROCESS = 0x20 Global Const $INTERACTIVE_PROCESS = 0x100 ; Error Control Global Const $USER_NOT_NOTIFIED = 0 Global Const $USER_NOTIFIED = 1 Global Const $RESTARTED_WITH_LAST_KNOWN_GOOD_CONFIG = 2 Global Const $ATTEMPTS_TO_START_WITH_A_GOOD_CONFIG = 3 ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ; _Service_GetInfo ; _Service_StartStop ; _Service_ChangeStartMode ; _Service_GetDependent ; _Service_GetObj ; =============================================================================================================================== ; #EXTENDED-TABLE# ============================================================================================================== ; 1 The request is not supported. ; 2 The user did not have the necessary access. ; 3 The service cannot be stopped because other services that are running are dependent on it. ; 4 The requested control code is not valid, or it is unacceptable to the service. ; 5 The requested control code cannot be sent to the service because the state of the service (Win32_BaseService State property) is equal to 0, 1, or 2. ; 6 The service has not been started. ; 7 The service did not respond to the start request in a timely fashion. ; 8 Unknown failure when starting the service. ; 9 The directory path to the service executable file was not found. ; 10 The service is already running. ; 11 The database to add a new service is locked. ; 12 A dependency this service relies on has been removed from the system. ; 13 The service failed to find the service needed from a dependent service. ; 14 The service has been disabled from the system. ; 15 The service does not have the correct authentication to run on the system. ; 16 This service is being removed from the system. ; 17 The service has no execution thread. ; 18 The service has circular dependencies when it starts. ; 19 A service is running under the same name. ; 20 The service name has invalid characters. ; 21 Invalid parameters have been passed to the service. ; 22 The account under which this service runs is either invalid or lacks the permissions to run the service. ; 23 The service exists in the database of services available from the system. ; 24 The service is currently paused in the system. ; =============================================================================================================================== #cs Create( [in] string Name, [in] string DisplayName, [in] string PathName, [in] uint8 ServiceType, [in] uint8 ErrorControl, [in] string StartMode, [in] boolean DesktopInteract, [in] string StartName, [in] string StartPassword, [in] string LoadOrderGroup, [in] string LoadOrderGroupDependencies[], [in] string ServiceDependencies[] #ce ; #FUNCTION# ==================================================================================================================== ; Name ..........: _Service_Create ; Description ...: Creates a service. ; Syntax ........: _Service_Create($_soService[, $_sComputer = '.']) ; Parameters ....: $_soService - Service name or service WMI-object ; $_sComputer - [optional] Computer name. Default is '.'. ; Author ........: BugFix ; Related .......: https://msdn.microsoft.com/en-us/library/windows/desktop/aa389390(v=vs.85).aspx #cs Const $OWN_PROCESS = 16 Const $NOT_INTERACTIVE = True $sComputer = "." $objWMIService = ObjGet("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") $objService = $objWMIService.Get("Win32_BaseService") $iErr = $objService.Create("DbService", _ ; Name (Name of the service to install to the Create method. 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-slashes (/) and double back-slashes (\) are invalid service name characters.) "Personnel Database", _ ; DisplayName (Display name of the service. This string has a maximum length of 256 characters. The name is case-preserved in the Service Control Manager. DisplayName comparisons are always case-insensitive.) "c:\windows\system32\db.exe", _ ; PathName (Fully qualified path to the executable file that implements the service.) $OWN_PROCESS, _ ; ServiceType (Type of services provided to processes that call them.) 2, _ ; ErrorControl (Severity of the error if the Create method fails to start. The value indicates the action taken by the startup program if failure occurs. All errors are logged by the system.) "Automatic", _ ; StartMode (Start mode of the Windows base service.) $NOT_INTERACTIVE, _ ; DesktopInteract (If true, the service can create or communicate with windows on the desktop.) ".\LocalSystem", _ ; StartName (Account name under which the service runs. Depending on the service type, the account name may be in the form of DomainName\Username or User Principal Name (UPN) format (Username@DomainName). The service process is logged using one of these two forms when it runs. If the account belongs to the built-in domain, .\Username can be specified. If NULL is specified, the service is logged on as the LocalSystem account. ) "" ; StartPassword (Password to the account name specified by the StartName parameter. Specify NULL if you are not changing the password. Specify an empty string if the service has no password.) Null, _ ; LoadOrderGroup (Group name associated with the new service.) Null, _ ; LoadOrderGroupDependencies[] (Array of load-ordering groups that must start before this service. Each item in the array is delimited by NULL and the list is terminated by two NULL values. In Visual Basic or script you can pass a vbArray.) Null) ; ServiceDependencies[] (Array that contains names of services that must start before this service starts. Each item in the array is delimited by NULL and the list is terminated by two NULL values. In Visual Basic or script you can pass a vbArray.) #ce ; =============================================================================================================================== Func _Service_Create($_sName, $_sDisplayName, $_sPathName, $_iServiceType, $_iErrorControl, $_sStartMode, $_fDesktopInteract, $_sStartName, _ $_sStartPassword='', $_sLoadOrderGroup=Null, $_aLoadOrderGroupDependencies=Null, $_aServiceDependencies=Null) ; EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: _Service_Delete ; Description ...: Deletes a service. ; Syntax ........: _Service_Delete($_soService[, $_sComputer = '.']) ; Parameters ....: $_soService - Service name or service WMI-object ; $_sComputer - [optional] Computer name. Default is '.'. ; Return values .: Success 1 ; Failure 0 set @error=1 Deletion has failed, see @extended (number from extended table) ; @error=2 can't get object ; Author ........: BugFix ; Related .......: https://msdn.microsoft.com/en-us/library/windows/desktop/aa389960(v=vs.85).aspx ; =============================================================================================================================== Func _Service_Delete($_soService, $_sComputer='.') Local $oService = $_soService If Not IsObj($oService) Then $oService = _Service_GetObj($_soService, $_sComputer) If @error Then Return SetError(2,0,0) $iErr = $oService.Delete() Return ($iErr = 0 ? 1 : SetError(1,$iErr,0)) EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: _Service_GetInfo ; Description ...: Reads StartMode, State and Status of an service. ; Syntax ........: _Service_GetInfo($_soService[, $_sComputer = '.'[, $_fRetAsStr = False]]) ; Parameters ....: $_soService - Service name or service WMI-object ; $_sComputer - [optional] Computer name. Default is '.'. ; $_fRetAsStr - [optional] Return the infos as string. Default (False) as combined integer (see enumareted global values) ; Return values .: String with infos or combined integer ; Failure 0 set @error 1 can't get object ; Author ........: BugFix ; Related .......: https://msdn.microsoft.com/en-us/library/windows/desktop/aa394418(v=vs.85).aspx ; =============================================================================================================================== Func _Service_GetInfo($_soService, $_sComputer='.', $_fRetAsStr=False) Local $oService = $_soService If Not IsObj($oService) Then $oService = _Service_GetObj($_soService, $_sComputer) If @error Then Return SetError(1,0,0) Local $sMode = $oService.StartMode, $sState = $oService.State, $sStatus = $oService.Status If $_fRetAsStr Then Return $sMode & ', ' & $sState & ', ' & $sStatus Local $aVal[] = ["Boot","System","Auto","Manual","Disabled", _ ; start mode "Stopped","Start Pending","Stop Pending","Running","Continue Pending","Pause Pending","Paused","Unknown", _ ; state "OK","Error","Degraded","Unknown","Pred Fail","Starting","Stopping","Service"] ; status Local $iRet = 0 For $i = 0 To UBound($aVal) -1 If $i < 5 Then If $sMode = $aVal[$i] Then $iRet = BitOR($iRet, 2^$i) ElseIf $i < 13 Then If $sState = $aVal[$i] Then $iRet = BitOR($iRet, 2^$i) Else If $sStatus = $aVal[$i] Then $iRet = BitOR($iRet, 2^$i) EndIf Next Return $iRet EndFunc ;==>_Service_GetInfo ; #FUNCTION# ==================================================================================================================== ; Name ..........: _Service_StartStop ; Description ...: Start or stop a service ; Syntax ........: _Service_StartStop($_soService[, $_sAction = 'start'[, $_sComputer = '.']]) ; Parameters ....: $_soService - Service name or service WMI-object ; $_sAction - [optional] 'stop' or 'start'. Default is 'start'. ; $_sComputer - [optional] Computer name. Default is '.'. ; Return values .: Success 1 ; Failure 0 set @error=1 resume has failed ; 0 2 start has failed ; 0 3 start has failed with service state 'unknown' ; collection 4 stop has failed while dependent services exists (returned as collection) ; 0 5 stop has failed ; 0 6 pause has failed ; @error 1-6: @extended = see number in extended table ; 0 7 pause has failed - service is stopped ; @error 8 can't get object ; Author ........: BugFix ; Related .......: https://msdn.microsoft.com/en-us/library/windows/desktop/aa393234(v=vs.85).aspx ; https://msdn.microsoft.com/en-us/library/windows/desktop/aa393660(v=vs.85).aspx ; https://msdn.microsoft.com/en-us/library/windows/desktop/aa393673(v=vs.85).aspx ; https://msdn.microsoft.com/en-us/library/windows/desktop/aa392733(v=vs.85).aspx ; =============================================================================================================================== Func _Service_StartStop($_soService, $_sAction='start', $_sComputer='.') Local $oService = $_soService If Not IsObj($oService) Then $oService = _Service_GetObj($_soService, $_sComputer) If @error Then Return SetError(8,0,0) Local $iInfo = _Service_GetInfo($oService), $iErr Switch $_sAction Case 'start', 'resume' ; service is running or will start or will be continued -> do nothing If BitAND($iInfo, BitOR($SST_Running, $SST_StartPending, $SST_ContinuePending)) Then Return 1 ; service is paused or will paused If BitAND($iInfo, BitOR($SST_Paused, $SST_PausePending)) Then $iErr = $oService.ResumeService() Return ($iErr = 0 ? 1 : SetError(1,$iErr,0)) ; service is stopped or will stopped ElseIf BitAND($iInfo, BitOR($SST_Stopped, $SST_StopPending)) Then $iErr = $oService.StartService() Return ($iErr = 0 ? 1 : SetError(2,$iErr,0)) Else ; state: UNKNOWN - try to start $iErr = $oService.StartService() Return ($iErr = 0 ? 1 : SetError(3,$iErr,0)) EndIf Case 'stop' ; service is stopped or will stopped If BitAND($iInfo, BitOR($SST_Stopped, $SST_StopPending)) Then Return 1 $iErr = $oService.StopService() Return ($iErr = 3 ? SetError(4,0,_Service_GetDependent($oService.Name, $oService.SystemName)) : ($iErr = 0 ? 1 : SetError(5,$iErr,0))) Case 'pause' ; service is paused or will paused If BitAND($iInfo, BitOR($SST_Paused, $SST_PausePending)) Then Return 1 If BitAND($iInfo, BitOR($SST_Stopped, $SST_StopPending)) Then Return SetError(7,0,0) $iErr = $oService.PauseService() Return ($iErr = 0 ? 1 : SetError(6,$iErr,0)) EndSwitch EndFunc ;==>_Service_StartStop ; #FUNCTION# ==================================================================================================================== ; Name ..........: _Service_ChangeStartMode ; Description ...: Changes the start mode of an service ; Syntax ........: _Service_ChangeStartMode($_soService[, $_sMode = 'Auto'[, $_sComputer = '.']]) ; Parameters ....: $_soService - Service name or service WMI-object ; $_sMode - [optional] The start mode. Default is 'Auto'. ; possible: 'Boot', 'System', 'Auto', 'Manual', 'Disabled' ; $_sComputer - [optional] Computer name. Default is '.'. ; Return values .: Success 1 ; Failure 0 set @error 1 change mode has failed ; @extended = see number in extended table ; @error 2 can't get object ; Author ........: BugFix ; Related .......: https://msdn.microsoft.com/en-us/library/windows/desktop/aa384896(v=vs.85).aspx ; =============================================================================================================================== Func _Service_ChangeStartMode($_soService, $_sMode='Auto', $_sComputer='.') Local $oService = $_soService If Not IsObj($oService) Then $oService = _Service_GetObj($_soService, $_sComputer) If @error Then Return SetError(2,0,0) Local $iErr = $oService.ChangeStartMode($_sMode) Return ($iErr = 0 ? 1 : SetError(1,$iErr,0)) EndFunc ;==>_Service_ChangeStartMode ; #FUNCTION# ==================================================================================================================== ; Name ..........: _Service_GetDependent ; Description ...: Get dependent services of an service ; Syntax ........: _Service_GetDependent($_soService[, $_sComputer = '.']) ; Parameters ....: $_soService - Service name or service WMI-object ; $_sComputer - [optional] Computer name. Default is '.'. ; Return values .: A collection of dependent services. ; Author ........: BugFix ; =============================================================================================================================== Func _Service_GetDependent($_soService, $_sComputer='.') Local $oWMI = ObjGet("winmgmts:\\" & $_sComputer & "\root\CIMV2") Local $sServiceName = $_soService If IsObj($sServiceName) Then $sServiceName = $sServiceName.Name Return $oWMI.ExecQuery("Associators of {Win32_Service.Name='" & $sServiceName & "'} Where " & _ "AssocClass=Win32_DependentService Role=Antecedent") EndFunc ;==>_Service_GetDependent ; #FUNCTION# ==================================================================================================================== ; Name ..........: _Service_GetObj ; Description ...: Gets the service as WMI-object ; Syntax ........: _Service_GetObj($_sServiceName[, $_sComputer = '.']) ; Parameters ....: $_sServiceName - Service name ; $_sComputer - [optional] Computer name. Default is '.'. ; Return values .: The WMI-object ; Author ........: BugFix ; =============================================================================================================================== Func _Service_GetObj($_sServiceName, $_sComputer='.') Local $oWMI = ObjGet("winmgmts:\\" & $_sComputer & "\root\CIMV2") Local $Timer = TimerInit() Do Sleep(50) Until IsObj($oWMI) Or TimerDiff($Timer) >= 3000 ; waits max. 3 sec If IsObj($oWMI) Then Return SetError(0,0,($oWMI.ExecQuery("SELECT * FROM Win32_Service WHERE Name='" & $_sServiceName & "'")).ItemIndex(0)) Else Return SetError(1,0,0) EndIf EndFunc ;==>_Service_GetObj