GetServicesInfo – Enumerate Windows NT services

GetServicesInfo – Enumerate Windows NT services

Option ExplicitPrivate Type SERVICE_STATUS   ' 28 bytes    dwServiceType As Long    dwCurrentState As Long    dwControlsAccepted As Long    dwWin32ExitCode As Long    dwServiceSpecificExitCode As Long    dwCheckPoint As Long    dwWaitHint As LongEnd TypePrivate Type ENUM_SERVICE_STATUS    ' 36 bytes    lpServiceName As Long    lpDisplayName As Long    ServiceStatus As SERVICE_STATUSEnd TypeConst SERVICE_ACTIVE = &H1&Const SERVICE_INACTIVE = &H2&Const SERVICE_ALL = SERVICE_ACTIVE + SERVICE_INACTIVEConst SC_MANAGER_ENUMERATE_SERVICE = &H4Const ERROR_MORE_DATA = 234Const SERVICE_WIN32_OWN_PROCESS = &H10&Const SERVICE_WIN32_SHARE_PROCESS = &H20&Const SERVICE_WIN32 = SERVICE_WIN32_OWN_PROCESS + SERVICE_WIN32_SHARE_PROCESS' values for a service's current stateConst SERVICE_STOPPED = 1           ' stoppedConst SERVICE_START_PENDING = 2     ' startingConst SERVICE_STOP_PENDING = 3      ' stoppingConst SERVICE_RUNNING = 4           ' runningConst SERVICE_CONTINUE_PENDING = 5  ' continuingConst SERVICE_PAUSE_PENDING = 6     ' pausingConst SERVICE_PAUSED = 7            ' paused' values for commands accepted by a service (biut-fielded)Const SERVICE_ACCEPT_STOP = 1Const SERVICE_ACCEPT_PAUSE_CONTINUE = 2Const SERVICE_ACCEPT_SHUTDOWN = 4Const SERVICE_ACCEPT_PARAMCHANGE = 8Const SERVICE_ACCEPT_NETBINDCHANGE = &H10Private Declare Function OpenSCManager Lib "advapi32.dll" Alias _    "OpenSCManagerA" (ByVal lpMachineName As String, _    ByVal lpDatabaseName As String, ByVal dwDesiredAccess As Long) As LongPrivate Declare Function EnumServicesStatus Lib "advapi32.dll" Alias _    "EnumServicesStatusA" (ByVal hSCManager As Long, _    ByVal dwServiceType As Long, ByVal dwServiceState As Long, _    lpServices As Any, ByVal cbBufSize As Long, pcbBytesNeeded As Long, _    lpServicesReturned As Long, lpResumeHandle As Long) As LongPrivate Declare Function CloseServiceHandle Lib "advapi32.dll" (ByVal hSCObject _    As Long) As LongPrivate Declare Function lstrcpy Lib "kernel32.dll" Alias "lstrcpyA" (szDest As _    String, szcSource As Long) As Long'Private Declare Function OpenService Lib "advapi32.dll" Alias "OpenServiceA" _    (ByVal hSCManager As Long, ByVal lpServiceName As String, _    ByVal dwDesiredAccess As Long) As Long' Return information on Windows NT services' it returns an array of Variants, where'   arrInfo(n, 0) is the service name (string)'   arrInfo(n, 1) is the service display name (string)'   arrInfo(n, 2) is the activation state of the service (enumerated)'   arrInfo(n, 3) is the set of commands accepted by the service (enumerated)' returns True if successful, False otherwise' if any error, call Err.LastDLLError for more informationFunction GetServicesInfo(arrInfo() As Variant) As Boolean    Dim hSCM As Long    Dim buffer As String * 256    Dim bytesNeeded As Long    Dim numberOfServices As Long    Dim handleNext As Long    Dim res As Long    Dim ndx As Long, i As Long        ' open the connection to Service Control Manager, exit if error    hSCM = OpenSCManager(vbNullString, vbNullString, _        SC_MANAGER_ENUMERATE_SERVICE)    If hSCM = 0 Then Exit Function        ' get buffer size in bytes, but without passing a buffer    handleNext = 0    EnumServicesStatus hSCM, SERVICE_WIN32, SERVICE_ALL, ByVal 0&, 0, _        bytesNeeded, 0, handleNext    ' we expect a MORE_DATA error    If Err.LastDllError <> ERROR_MORE_DATA Then GoTo CleanUp        ' evaluate the number of services    '###########################################################    ' original line: numberOfServices = bytesNeeded / 36    ' patch proposed by Klaus Pater to make this routine compatible with    ' WinNT/2000 workstation    numberOfServices = bytesNeeded / 36 + 1        ' Redimension the array to receive info on the services    ReDim ServicesInfo(1 To numberOfServices) As ENUM_SERVICE_STATUS        ' do the call again, this time passing the actual buffer    handleNext = 0    res = EnumServicesStatus(hSCM, SERVICE_WIN32, SERVICE_ALL, ServicesInfo(1), _        Len(ServicesInfo(1)) * numberOfServices, bytesNeeded, numberOfServices, _        handleNext)    ' error if previous function returns zero    If res = 0 Then GoTo CleanUp        ' fill the result array    ReDim arrInfo(1 To numberOfServices, 0 To 3)    For ndx = 1 To numberOfServices        ' move service name into buffer and then to the array        lstrcpy ByVal buffer, ByVal ServicesInfo(ndx).lpServiceName        arrInfo(ndx, 0) = Left$(buffer, InStr(buffer, vbNullChar) - 1)        ' move service display name into buffer and then to the array        lstrcpy ByVal buffer, ByVal ServicesInfo(ndx).lpDisplayName        arrInfo(ndx, 1) = Left$(buffer, InStr(buffer, vbNullChar) - 1)        ' move activation state and accepted commands into result array        arrInfo(ndx, 2) = ServicesInfo(ndx).ServiceStatus.dwCurrentState        arrInfo(ndx, 3) = ServicesInfo(ndx).ServiceStatus.dwControlsAccepted    Next        ' return success    GetServicesInfo = TrueCleanUp:    ' close the SCM    CloseServiceHandle hSCMEnd Function

See also  11 Effective Keyword Research Tools and Techniques

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist