Microsoft KB Archive/189633

= How To Query a Service for Status and Configuration =

Article ID: 189633

Article Last Modified on 7/1/2004

-

APPLIES TO


 * Microsoft Visual Basic 5.0 Control Creation Edition
 * Microsoft Visual Basic 5.0 Professional Edition
 * Microsoft Visual Basic 6.0 Professional Edition
 * Microsoft Visual Basic 5.0 Enterprise Edition
 * Microsoft Visual Basic 6.0 Enterprise Edition

-



This article was previously published under Q189633



SUMMARY
This article provides sample code that demonstrates how to query a Windows 2000 or Windows NT Service's Status and Configuration from Visual Basic.



Step-by-Step Example
 Start a New Standard EXE Project in Visual Basic. Form1 is created by default. Add a Text Box, Command Button, and a List Box to Form1. Remove "Text1" from the Text property of Text1.  Paste the following code into the declarations section of Form1: Option Explicit

Private Declare Function CloseServiceHandle Lib "advapi32.dll" _ (ByVal hSCObject As Long) As Long

Private Declare Function QueryServiceStatus Lib "advapi32.dll" _ (ByVal hService As Long, _     lpServiceStatus As SERVICE_STATUS) 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

Private Declare Function OpenSCManager Lib "advapi32.dll" _ Alias "OpenSCManagerA" _ (ByVal lpMachineName As String, _     ByVal lpDatabaseName As String, _      ByVal dwDesiredAccess As Long) As Long

Private Declare Function QueryServiceConfig Lib "advapi32.dll" _ Alias "QueryServiceConfigA" _ (ByVal hService As Long, _     lpServiceConfig As Byte, _      ByVal cbBufSize As Long, _      pcbBytesNeeded As Long) As Long

Private Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" _ (hpvDest As Any, _     hpvSource As Any, _      ByVal cbCopy As Long)

Private Declare Function lstrcpy Lib "KERNEL32" Alias "lstrcpyA" _ (ByVal lpString1 As String, _     ByVal lpString2 As Long) As Long

Private 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

Private Type QUERY_SERVICE_CONFIG dwServiceType As Long dwStartType As Long dwErrorControl As Long lpBinaryPathName As Long 'String lpLoadOrderGroup As Long ' String dwTagId As Long lpDependencies As Long 'String lpServiceStartName As Long 'String lpDisplayName As Long 'String End Type

Private Const SERVICE_STOPPED = &H1 Private Const SERVICE_START_PENDING = &H2 Private Const SERVICE_STOP_PENDING = &H3 Private Const SERVICE_RUNNING = &H4 Private Const SERVICE_CONTINUE_PENDING = &H5 Private Const SERVICE_PAUSE_PENDING = &H6 Private Const SERVICE_PAUSED = &H7 Private Const SERVICE_ACCEPT_STOP = &H1 Private Const SERVICE_ACCEPT_PAUSE_CONTINUE = &H2 Private Const SERVICE_ACCEPT_SHUTDOWN = &H4 Private Const SC_MANAGER_CONNECT = &H1 Private Const SERVICE_INTERROGATE = &H80 Private Const GENERIC_READ = &H80000000 Private Const ERROR_INSUFFICIENT_BUFFER = 122

Private Sub Command1_Click Dim hSCM As Long Dim hSVC As Long Dim pSTATUS As SERVICE_STATUS Dim udtConfig As QUERY_SERVICE_CONFIG Dim lRet As Long Dim lBytesNeeded As Long Dim sTemp As String Dim pFileName As Long

List1.Clear

' Open The Service Control Manager '     hSCM = OpenSCManager(vbNullString, vbNullString, SC_MANAGER_CONNECT) If hSCM = 0 Then MsgBox "Error - " & Err.LastDllError End If

' Open the specific Service to obtain a handle '     hSVC = OpenService(hSCM, Trim(Text1.Text), GENERIC_READ) If hSVC = 0 Then MsgBox "Error - " & Err.LastDllError GoTo CloseHandles End If

' Fill the Service Status Structure '     lRet = QueryServiceStatus(hSVC, pSTATUS) If lRet = 0 Then MsgBox "Error - " & Err.LastDllError GoTo CloseHandles End If

' Report the Current State '     Select Case pSTATUS.dwCurrentState Case SERVICE_STOPPED sTemp = "The Service is Stopped" Case SERVICE_START_PENDING sTemp = "The Service Being Started" Case SERVICE_STOP_PENDING sTemp = "The Service is in the process of being stopped" Case SERVICE_RUNNING sTemp = "The Service is Running" Case SERVICE_CONTINUE_PENDING sTemp = "The Service is in the process of being Continued" Case SERVICE_PAUSE_PENDING sTemp = "The Service is in the process of being Paused" Case SERVICE_PAUSED sTemp = "The Service is Paused" Case SERVICE_ACCEPT_STOP sTemp = "The Service is Stopped" Case SERVICE_ACCEPT_PAUSE_CONTINUE sTemp = "The Service is " Case SERVICE_ACCEPT_SHUTDOWN sTemp = "The Service is being Shutdown" End Select

List1.AddItem "Service Status : " & sTemp

' Call QueryServiceConfig with 1 byte buffer to generate an error ' that returns the size of a buffer we need. '     ReDim abConfig(0) As Byte lRet = QueryServiceConfig(hSVC, abConfig(0), 0&, lBytesNeeded) If lRet = 0 And Err.LastDllError <> ERROR_INSUFFICIENT_BUFFER Then MsgBox "Error - " & Err.LastDllError End If

' Redim our byte array to the size necessary and call ' QueryServiceConfig again '     ReDim abConfig(lBytesNeeded) As Byte lRet = QueryServiceConfig(hSVC, abConfig(0), lBytesNeeded, _        lBytesNeeded) If lRet = 0 Then MsgBox "Error - " & Err.LastDllError GoTo CloseHandles End If

' Fill our Service Config User Defined Type. '     CopyMemory udtConfig, abConfig(0), Len(udtConfig)

List1.AddItem "Service Type: " & udtConfig.dwServiceType List1.AddItem "Service Start Type: " & udtConfig.dwStartType List1.AddItem "Service Error Control: " & udtConfig.dwErrorControl

sTemp = Space(255)

' Now use the pointer obtained to copy the path into the temporary ' String Variable '     lRet = lstrcpy(sTemp, udtConfig.lpBinaryPathName) List1.AddItem "Service Binary Path: " & sTemp

lRet = lstrcpy(sTemp, udtConfig.lpDependencies) List1.AddItem "Service Dependencies: " & sTemp

lRet = lstrcpy(sTemp, udtConfig.lpDisplayName) List1.AddItem "Service DisplayName: " & sTemp

lRet = lstrcpy(sTemp, udtConfig.lpLoadOrderGroup) List1.AddItem "Service LoadOrderGroup: " & sTemp

lRet = lstrcpy(sTemp, udtConfig.lpServiceStartName) List1.AddItem "Service Start Name: " & sTemp

CloseHandles: ' Close the Handle to the Service '     CloseServiceHandle (hSVC)

' Close the Handle to the Service Control Manager '     CloseServiceHandle (hSCM)

End Sub  Run the sample and type the Service Name in the Text box. For this example type in "Eventlog" without the quotes.

NOTE: This is not necessarily the same as the "Display Name" that shows in the Services applet of the Control Panel. The Service names registered on the system can be located under the following registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services  Click the CommandButton.

The results displayed in the list box should be similar to the following:      Service Status : The Service is Running Service Type: 32 Service Start Type: 2 Service Error Control: 1 Service Binary Path: C:\WINNT\system32\services.exe Service Dependencies:

Service DisplayName: EventLog Service LoadOrderGroup: Event log Service Start Name: LocalSystem

</li></ol>

Keywords: kbhowto kbregistry KB189633

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.