Bilgus Posted June 17, 2016 Share Posted June 17, 2016 (edited) I recently needed a way to enumerate services, I found this UDF but when running _Service_Enum the 300 ms delay was too long for me so I went and optimized the code now it runs over 10x quicker (~20ms) I may update the other functions if I have a use for them. expandcollapse popupFunc _Service_Enum($iServiceType, $iServiceState = $SERVICE_STATE_ALL, $sLoadOrderGroup = Default, $sComputerName = "") ;Local $SC_ENUM_PROCESS_INFO = 0 Local $tLoadOrderGroup, $iErr Local $hSCM, $uEBuf, $tEBuf, $avEnumSvc $tLoadOrderGroup = DllStructCreate("char[" & Number($sLoadOrderGroup <> Default) * (StringLen($sLoadOrderGroup) + 1) & "]") DllStructSetData($tLoadOrderGroup, 1, $sLoadOrderGroup) ;open service manager $hSCM = OpenSCManager($sComputerName, $SC_MANAGER_ENUMERATE_SERVICE) ; Determine needed size of the struct in bytes $avEnumSvc = DllCall("advapi32.dll", "int", "EnumServicesStatusEx", _ "hwnd", $hSCM, _ "dword", $SC_ENUM_PROCESS_INFO, _ "dword", $iServiceType, _ "dword", $iServiceState, _ "ptr", 0, _ "dword", 0, _ "dword*", 0, _ "dword*", 0, _ "dword*", 0, _ "ptr", DllStructGetPtr($tLoadOrderGroup)) ; Load buffer with Service data $uEBuf = DllStructCreate("ubyte[" & $avEnumSvc[7] & "]") ;ubyte buffer $avEnumSvc = DllCall("advapi32.dll", "int", "EnumServicesStatusEx", _ "hwnd", $hSCM, _ "dword", $SC_ENUM_PROCESS_INFO, _ "dword", $iServiceType, _ "dword", $iServiceState, _ "ptr", DllStructGetPtr($uEBuf), _ ;5-lpServices "dword", DllStructGetSize($uEBuf), _ ;6-cbBufSize "dword*", 0, _ ;7-pcbBytesNeeded "dword*", 0, _ ;8-lpServicesReturned "dword*", 0, _ ;9-lpResumeHandle "ptr", DllStructGetPtr($tLoadOrderGroup)) ;10-pszGroupName ; Get last error and close service control manager database handle If $avEnumSvc[0] = 0 Then $iErr = _WinAPI_GetLastError() CloseServiceHandle($hSCM) Local $asSvcsStatus[$avEnumSvc[8] + 1][11] = [[$avEnumSvc[8], 11]] ;Prepare return Array ; Decode the ubyte structure For $i = 1 To $avEnumSvc[8] $tEBuf = DllStructCreate("uint_ptr[2];dword[9]", $avEnumSvc[5] + (DllStructGetSize($tEBuf) * ($i - 1))) ;Prepare buffer increment pointer by struct sz For $k = 0 To 1 $asSvcsStatus[$i][$k] = DllStructGetData(DllStructCreate("char[257]", DllStructGetData($tEBuf, 1, $k + 1)), 1) ;fill char array with info from ptr Next For $k = 1 To UBound($asSvcsStatus, 2) - 2 $asSvcsStatus[$i][$k + 1] = DllStructGetData($tEBuf, 2, $k) Next Next Return SetError($iErr, 0, $asSvcsStatus) EndFunc ;==>_Service_Enum I reworked the parsing to use less temporary variables and less copying, Should be a drop in replacement. Edited June 17, 2016 by Bilgus fixed typo in buffer name Link to comment Share on other sites More sharing options...
ViciousXUSMC Posted September 25, 2018 Share Posted September 25, 2018 (edited) Sorry for the Nekro. This is the best services UDF I have seen. I used it with great success to fix a bad application that was growing out of control with temp files. I have a new project I am working on right now, and unlike last time I used it I am not running it local, but instead trying to start/stop/query services on a remote server as I have a cluster of servers that need services stopped/started in a special order. I made the code, and now in testing it is not working. I get an Error Code of 6 for @Error for Service_Stop and I am a admin on the remote server. I am not sure if its security/permissions issues, or something else. #Edit# Still works - We had a crazy server name and I was missing a letter. Edited September 25, 2018 by ViciousXUSMC Link to comment Share on other sites More sharing options...
TJF Posted September 8, 2020 Share Posted September 8, 2020 How can I get an overview of all available services and their startup type with this UDF (to change some startup types afterwards)? Link to comment Share on other sites More sharing options...
TJF Posted September 9, 2020 Share Posted September 9, 2020 Ok. Can get it this way (cmd): sc query state= all argumentum 1 Link to comment Share on other sites More sharing options...
Leendert-Jan Posted September 10, 2021 Share Posted September 10, 2021 Thank you very much! This is very usefull, since services.msc ignores keyboard and mouse input from AutoIt. (At least for me) Link to comment Share on other sites More sharing options...
Dotaznik Posted December 2, 2022 Share Posted December 2, 2022 I cannot figure out, why syntax check post this errors when I include this UDF ; Includes #include <MsgBoxConstants.au3> #include <Services.au3> #include <SecurityConstants.au3> "C:\Program Files (x86)\AutoIt3\Include\Services.au3"(481,61) : warning: $RIGHTS_DELETE: possibly used before declaration. $hService = OpenService($hSC, $sServiceName, $RIGHTS_DELETE) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ "C:\Program Files (x86)\AutoIt3\Include\Services.au3"(481,61) : error: $RIGHTS_DELETE: undeclared global variable. $hService = OpenService($hSC, $sServiceName, $RIGHTS_DELETE) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ Link to comment Share on other sites More sharing options...
Dotaznik Posted December 2, 2022 Share Posted December 2, 2022 Ah, it is script breaking change in v v3.3.16.0, SecurityConstants.au3 has been addapted to avoid naming confict. So $RIGHTS_DELETE, $SYNCHRONIZE, have been renamed to $STANDARD_*. NoNameCode 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now