This demo builds upon the EnumServicesStatus basic demo, adding
functions returning both the type of service, and the type of control that the service allows (handles). It also provides for displaying only
the active (running) or inactive services alone, as well as listing all services on the local machine. EnumServicesStatus requires Windows NT
3.1 or later.
|
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
' applications, but you may not reproduce
' or publish this code on any web site,
' online service, or distribute as source
' on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'our own constant
Public Const SIZEOF_SERVICE_STATUS As Long = 36
'windows constants
Public Const LB_SETTABSTOPS As Long = &H192
Public Const ERROR_MORE_DATA = 234
Public Const SC_MANAGER_ENUMERATE_SERVICE = &H4
'Service State for Enum Requests (Bit Mask)
Public Const SERVICE_ACTIVE = &H1
Public Const SERVICE_INACTIVE = &H2
Public Const SERVICE_STATE_ALL = SERVICE_ACTIVE Or SERVICE_INACTIVE
'Service Types (Bit Mask)
'corresponds to SERVICE_STATUS.dwServiceType
Public Const SERVICE_KERNEL_DRIVER As Long = &H1
Public Const SERVICE_FILE_SYSTEM_DRIVER As Long = &H2
Public Const SERVICE_ADAPTER As Long = &H4
Public Const SERVICE_RECOGNIZER_DRIVER As Long = &H8
Public Const SERVICE_WIN32_OWN_PROCESS As Long = &H10
Public Const SERVICE_WIN32_SHARE_PROCESS As Long = &H20
Public Const SERVICE_INTERACTIVE_PROCESS As Long = &H100
Public Const SERVICE_WIN32 As Long = SERVICE_WIN32_OWN_PROCESS Or _
SERVICE_WIN32_SHARE_PROCESS
Public Const SERVICE_DRIVER As Long = SERVICE_KERNEL_DRIVER Or _
SERVICE_FILE_SYSTEM_DRIVER Or _
SERVICE_RECOGNIZER_DRIVER
Public Const SERVICE_TYPE_ALL As Long = SERVICE_WIN32 Or _
SERVICE_ADAPTER Or _
SERVICE_DRIVER Or _
SERVICE_INTERACTIVE_PROCESS
'Service State
'corresponds to SERVICE_STATUS.dwCurrentState
Public Const SERVICE_STOPPED As Long = &H1
Public Const SERVICE_START_PENDING As Long = &H2
Public Const SERVICE_STOP_PENDING As Long = &H3
Public Const SERVICE_RUNNING As Long = &H4
Public Const SERVICE_CONTINUE_PENDING As Long = &H5
Public Const SERVICE_PAUSE_PENDING As Long = &H6
Public Const SERVICE_PAUSED As Long = &H7
'Controls Accepted (Bit Mask)
'corresponds to SERVICE_STATUS.dwControlsAccepted
Public Const SERVICE_ACCEPT_STOP As Long = &H1
Public Const SERVICE_ACCEPT_PAUSE_CONTINUE As Long = &H2
Public Const SERVICE_ACCEPT_SHUTDOWN As Long = &H4
'Windows type used to call the Net API
Public Const MAX_PREFERRED_LENGTH As Long = -1
Public Const NERR_SUCCESS As Long = 0&
Public Const SV_TYPE_WORKSTATION As Long = &H1
Public Const SV_TYPE_SERVER As Long = &H2
Public Const SV_TYPE_SQLSERVER As Long = &H4
Public Const SV_TYPE_DOMAIN_CTRL As Long = &H8
Public Const SV_TYPE_DOMAIN_BAKCTRL As Long = &H10
Public Const SV_TYPE_TIME_SOURCE As Long = &H20
Public Const SV_TYPE_AFP As Long = &H40
Public Const SV_TYPE_NOVELL As Long = &H80
Public Const SV_TYPE_DOMAIN_MEMBER As Long = &H100
Public Const SV_TYPE_PRINTQ_SERVER As Long = &H200
Public Const SV_TYPE_DIALIN_SERVER As Long = &H400
Public Const SV_TYPE_XENIX_SERVER As Long = &H800
Public Const SV_TYPE_SERVER_UNIX As Long = SV_TYPE_XENIX_SERVER
Public Const SV_TYPE_NT As Long = &H1000
Public Const SV_TYPE_WFW As Long = &H2000
Public Const SV_TYPE_SERVER_MFPN As Long = &H4000
Public Const SV_TYPE_SERVER_NT As Long = &H8000
Public Const SV_TYPE_POTENTIAL_BROWSER As Long = &H10000
Public Const SV_TYPE_BACKUP_BROWSER As Long = &H20000
Public Const SV_TYPE_MASTER_BROWSER As Long = &H40000
Public Const SV_TYPE_DOMAIN_MASTER As Long = &H80000
Public Const SV_TYPE_SERVER_OSF As Long = &H100000
Public Const SV_TYPE_SERVER_VMS As Long = &H200000
Public Const SV_TYPE_WINDOWS As Long = &H400000 'Windows95 and above
Public Const SV_TYPE_DFS As Long = &H800000 'Root of a DFS tree
Public Const SV_TYPE_CLUSTER_NT As Long = &H1000000 'NT Cluster
Public Const SV_TYPE_TERMINALSERVER As Long = &H2000000 'Terminal Server
Public Const SV_TYPE_DCE As Long = &H10000000 'IBM DSS or equi
Public Const SV_TYPE_ALTERNATE_XPORT As Long = &H20000000 'return alternate transport
Public Const SV_TYPE_LOCAL_LIST_ONLY As Long = &H40000000 'local list only
Public Const SV_TYPE_DOMAIN_ENUM As Long = &H80000000
Public Const SV_TYPE_ALL As Long = &HFFFFFFFF
Public Const SV_PLATFORM_ID_OS2 As Long = 400
Public Const SV_PLATFORM_ID_NT As Long = 500
'Mask applied to svX_version_major in
'order to obtain the major version number.
Public Const MAJOR_VERSION_MASK As Long = &HF
Public Type SERVICE_STATUS
dwServiceType As Long
dwCurrentState As Long
dwControlsAccepted As Long
dwWin32ExitCode As Long
dwServiceSpecificExitCode As Long
dwCheckPoint As Long
dwWaitHint As Long
End Type
Public Type ENUM_SERVICE_STATUS
lpServiceName As Long
lpDisplayName As Long
ServiceStatus As SERVICE_STATUS
End Type
Public Declare Function OpenSCManager Lib "advapi32" _
Alias "OpenSCManagerA" _
(ByVal lpMachineName As String, _
ByVal lpDatabaseName As String, _
ByVal dwDesiredAccess As Long) As Long
Public Declare Function EnumServicesStatus Lib "advapi32" _
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 Long
Public Declare Function CloseServiceHandle Lib "advapi32" _
(ByVal hSCObject As Long) As Long
Public Declare Function lstrcpyA Lib "kernel32" _
(ByVal RetVal As String, _
ByVal Ptr As Long) As Long
Public Declare Function lstrlenA Lib "kernel32" _
(ByVal Ptr As Any) As Long
Public Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
|
Option Explicit
Private Sub Form_Load()
ReDim TabArray(0 To 4) As Long
TabArray(0) = 150
TabArray(1) = 220
TabArray(2) = 270
TabArray(3) = 342
TabArray(4) = 390
Call SendMessage(List1.hwnd, LB_SETTABSTOPS, 0&, ByVal 0&)
Call SendMessage(List1.hwnd, LB_SETTABSTOPS, 5&, TabArray(0))
List1.Refresh
Command1.Caption = "Active"
Command2.Caption = "Inactive"
Command3.Caption = "All"
End Sub
Private Sub Command1_Click()
'active services
EnumSystemServices SERVICE_ACTIVE, List1
End Sub
Private Sub Command2_Click()
'inactive services
EnumSystemServices SERVICE_INACTIVE, List1
End Sub
Private Sub Command3_Click()
'all services
EnumSystemServices SERVICE_STATE_ALL, List1
End Sub
Public Function EnumSystemServices(SERVICE_TYPE As Long, _
ctl As Control) As Long
Dim hSCManager As Long
Dim pntr() As ENUM_SERVICE_STATUS
Dim cbBuffSize As Long
Dim cbRequired As Long
Dim dwReturned As Long
Dim hEnumResume As Long
Dim cbBuffer As Long
Dim success As Long
Dim i As Long
'these five just help keep the
'code lines from becoming too long
'for html display
Dim sSvcName As String
Dim sDispName As String
Dim dwState As Long
Dim dwType As Long
Dim dwCtrls As Long
'establish a connection to the service control
'manager on the local computer and open
'the local service control manager database.
hSCManager = OpenSCManager(vbNullString, _
vbNullString, _
SC_MANAGER_ENUMERATE_SERVICE)
If hSCManager <> 0 Then
'Get buffer size by calling EnumServicesStatus.
'To determine the required buffer size, call EnumServicesStatus
'with cbBuffer and hEnumResume set to zero. EnumServicesStatus
'fails (returns 0), and Err.LastDLLError returns ERROR_MORE_DATA,
'filling cbRequired with the size, in bytes, of the buffer
'required to hold the array of structures and their data.
success = EnumServicesStatus(hSCManager, _
SERVICE_WIN32, _
SERVICE_TYPE, _
ByVal &H0, _
&H0, _
cbRequired, _
dwReturned, _
hEnumResume)
'If success is 0 and the LastDllError is
'ERROR_MORE_DATA, use returned info to create
'the required data buffer
If success = 0 And Err.LastDllError = ERROR_MORE_DATA Then
'Calculate number of structures needed
'and redimension the array
cbBuffer = (cbRequired \ SIZEOF_SERVICE_STATUS) + 1
ReDim pntr(0 To cbBuffer)
'Set cbBuffSize equal to the size of the buffer
cbBuffSize = cbBuffer * SIZEOF_SERVICE_STATUS
'Enumerate the services. If the function succeeds,
'the return value is nonzero. If the function fails,
'the return value is zero. In addition, hEnumResume
'must be set to 0.
hEnumResume = 0
If EnumServicesStatus(hSCManager, _
SERVICE_WIN32, _
SERVICE_TYPE, _
pntr(0), _
cbBuffSize, _
cbRequired, _
dwReturned, _
hEnumResume) Then
'pntr() array is now filled with service data,
'so it is a simple matter of extracting the
'required information.
With ctl
.Clear
For i = 0 To dwReturned - 1
sDispName = GetStrFromPtrA(ByVal pntr(i).lpDisplayName)
sSvcName = GetStrFromPtrA(ByVal pntr(i).lpServiceName)
dwState = pntr(i).ServiceStatus.dwCurrentState
dwType = pntr(i).ServiceStatus.dwServiceType
dwCtrls = pntr(i).ServiceStatus.dwControlsAccepted
.AddItem sDispName & vbTab & _
sSvcName & vbTab & _
GetServiceState(dwState) & vbTab & _
GetServiceType(dwType) & vbTab & _
GetServiceControl(dwCtrls)
Next
End With
Else
MsgBox "EnumServicesStatus; error " & _
CStr(Err.LastDllError)
End If 'If EnumServicesStatus
Else
MsgBox "ERROR_MORE_DATA not returned; error " & _
CStr(Err.LastDllError)
End If 'If success = 0 And Err.LastDllError
Else
MsgBox "OpenSCManager failed; error = " & _
CStr(Err.LastDllError)
End If 'If hSCManager <> 0
'clean up
Call CloseServiceHandle(hSCManager)
'return the number of services
'returned as a sign of success
EnumSystemServices = dwReturned
End Function
Public Function GetStrFromPtrA(ByVal lpszA As Long) As String
GetStrFromPtrA = String$(lstrlenA(ByVal lpszA), 0)
Call lstrcpyA(ByVal GetStrFromPtrA, ByVal lpszA)
End Function
Private Function GetServiceControl(dwControl As Long) As String
Dim tmp As String
If dwControl Then
If (dwControl And SERVICE_ACCEPT_STOP) Then tmp = tmp & "stop, "
If (dwControl And SERVICE_ACCEPT_PAUSE_CONTINUE) Then tmp = tmp & "pause, "
If (dwControl And SERVICE_ACCEPT_SHUTDOWN) Then tmp = tmp & "shutdown"
'Else
' tmp = vbTab
End If
GetServiceControl = tmp
End Function
Private Function GetServiceType(dwType As Long) As String
Dim tmp As String
If (dwType And SERVICE_WIN32_OWN_PROCESS) Then tmp = tmp & "own proc, "
If (dwType And SERVICE_WIN32_SHARE_PROCESS) Then tmp = tmp & "share, "
If (dwType And SERVICE_KERNEL_DRIVER) Then tmp = tmp & "kernel, "
If (dwType And SERVICE_FILE_SYSTEM_DRIVER) Then tmp = tmp & "filesys, "
If (dwType And SERVICE_INTERACTIVE_PROCESS) Then tmp = tmp & "interactive"
GetServiceType = tmp
End Function
Private Function GetServiceState(dwState As Long) As String
Select Case dwState
Case SERVICE_STOPPED: GetServiceState = "stopped"
Case SERVICE_START_PENDING: GetServiceState = "startpend"
Case SERVICE_STOP_PENDING: GetServiceState = "stoppend"
Case SERVICE_RUNNING: GetServiceState = "running"
Case SERVICE_CONTINUE_PENDING: GetServiceState = "contpend"
Case SERVICE_PAUSE_PENDING: GetServiceState = "pausepend"
Case SERVICE_PAUSED: GetServiceState = "paused"
End Select
End Function |