Microsoft Access VBA Uses WMI to Control Windows Services

You can Stop, Start, Pause, and Resume Windows Services with Microsoft Access VBA by using the power of WMI (Windows Management Instrumentation). This is called “setting the State” of the Service. This can be useful, for example, if we want to make sure the SQL Server Reporting Services is running. We may also want to stop a service we do not need that is using up computer resources.

We can use the “Update Services Data” button on our Form to get the current information about all Windows Services on our computer. The current State of the Service is displayed in the “State” text box, which is encircled in orange.


Our Form provides essential information we need before we attempt to set the state of the Service. The “AcceptPause” value informs us if we can Pause the Service and the “AcceptStop” value indicates if the Service can be Stopped.

If we want to change the State of a Service we use the Combo box encircled in Red. The label displays the different States of a Service which are used as a Value List of the Combo box. They are Start, Stop, Pause, and Resume. When we select the desired State the Combo box AfterUpdate Event is used to set the State of the Service.

Private Sub cmdStopService_Click()

    Dim strServiceState As String
    Dim strServiceName As String

    ' Get the name of the current record's Service
    strServiceName = Me.txtName.Value

    ' Get the Selected State
    strServiceState = Me.cboSetServiceState.Value

    ' Call a Function to set the Service State
    ' passing the Service Name and the selected State
    Call SetServiceState(strServiceName, strServiceState)

End Sub

We could have used a button and a Function to set each State, but we decided to use just one procedure to set any of the four possible States. Much of the code in the next procedure has been discussed in previous articles.

Function SetServiceState(strServiceName As String, strServiceState As String) As Long

    Dim objWMIService As Object
    Dim colServices As Object
    Dim objService As Object
    Dim strComputer As String
    Dim strErrorMessage As String
    Dim errReturnCode As Long

    DoCmd.Hourglass True

    ' Set an error code not used by Microsoft
    errReturnCode = 9999

    strComputer = "."

    Set objWMIService = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\" _
        & strComputer & "\root\cimv2")

    Set colServices = objWMIService.ExecQuery _
        ("SELECT * FROM win32_Service" & _
        " WHERE Name = '" & strServiceName & "'")

    For Each objService In colServices
         ' Use Select Case to set the chosen Service State
        Select Case strServiceState
            Case "Start"
                errReturnCode = objService.StartService()

            Case "Stop"
                errReturnCode = objService.StopService()

            Case "Pause"
                errReturnCode = objService.PauseService()

            Case "Resume"
                errReturnCode = objService.ResumeService()
        End Select
    Next

    DoCmd.Hourglass False

    ' Get and display the results of the code
    Select Case errReturnCode
        Case Is = 0
            MsgBox "Service " & strServiceName & " has been changed to " _
                & strServiceState & " successfully.     ", vbInformation
        Case Is = 9999
            ' If errReturnCode has not changed the Service was not found
            MsgBox "Service """ & strServiceName & """ was not found" & _
                " and may not exist.       ", vbCritical
        Case Else
            ' Get the error messages supplied by Microsoft
            strErrorMessage = ErrReturnStateChange(errReturnCode)
            MsgBox "Service " & strServiceName _
                & " State change failed.      " & vbCrLf & "Reason: " _
                & strErrorMessage & "       ", vbExclamation _
                , "Service State Change Failed"
    End Select

    SetServiceState = errReturnCode

    Set objService = Nothing
    Set colServices = Nothing
    Set objWMIService = Nothing

End Function

Again we have used the error documentation provided by Microsoft to write the error code return procedure. Fortunately, the error codes for all four of the State Change Methods are the same, which enables us to use just one procedure.

Function ErrReturnStateChange(lngerrReturn As Long) As String

    Select Case lngerrReturn
        Case Is = 0
            ErrReturnStateChange = "Success"
        Case Is = 1
            ErrReturnStateChange = "Not Supported"
        Case Is = 2
            ErrReturnStateChange = "Access Denied"
        Case Is = 3
            ErrReturnStateChange = "Dependent Services Running"
        Case Is = 4
            ErrReturnStateChange = "Invalid Service Control"
        Case Is = 5
            ErrReturnStateChange = "Service Cannot Accept Control"
        Case Is = 6
            ErrReturnStateChange = "Service Not Active"
        Case Is = 7
            ErrReturnStateChange = "Service Request timeout"
        Case Is = 8
            ErrReturnStateChange = "Unknown Failure"
        Case Is = 9
            ErrReturnStateChange = "Path Not Found"
        Case Is = 10
            ErrReturnStateChange = "Service Already Stopped"
        Case Is = 11
            ErrReturnStateChange = "Service Database Locked"
        Case Is = 12
            ErrReturnStateChange = "Service Dependency Deleted"
        Case Is = 13
            ErrReturnStateChange = "Service Dependency Failure"
        Case Is = 14
            ErrReturnStateChange = "Service Disabled"
        Case Is = 15
            ErrReturnStateChange = "Service Logon Failed"
        Case Is = 16
            ErrReturnStateChange = "Service Marked For Deletion"
        Case Is = 17
            ErrReturnStateChange = "Service No Thread"
        Case Is = 18
            ErrReturnStateChange = "Status Circular Dependency"
        Case Is = 19
            ErrReturnStateChange = "Status Duplicate Name"
        Case Is = 20
            ErrReturnStateChange = "Status - Invalid Name"
        Case Is = 21
            ErrReturnStateChange = "Status - Invalid Parameter"
        Case Is = 22
            ErrReturnStateChange = "Status - Invalid Service Account"
        Case Is = 23
            ErrReturnStateChange = "Status - Service Exists"
        Case Is = 24
            ErrReturnStateChange = "Service Already Paused"
    End Select

End Function


So to change the State of a Windows Service with our Form, we first update the Services data with the “Update Services Data” button. Then we use the “Find Service” Combo box to go to the record of the selected Service. We can then read the “State” text box to see if the Service’s State is already set to what we want. We also need to check the “Start Mode” text box to see if the Service is Disabled. If so, we need to change the Start Mode to “Manual” or “Automatic” before we can set the State of the Service. We should also look at the “AcceptPause” and the “AcceptStop” text boxes to determine if we can set the State we want. We can then set the State of the Process using the Start, Stop, Pause, Resume Service combo box.


We look forward to discovering more of the power of using WMI with VBA in our next article.


You can download the free sample database, WMISample.zip which contains the Form and the code used in this article at our Gaining Access website.


More Free Downloads:
Us or UK/AU Pop-up Calendar
Report Date Dialog Form in US or UK/AU Version.
ScopeSight for Access Reports Demo: get the exact data you want on your Access Reports.
Free Church Management Software now with new Contributions management.
Code Samples


Are your emails stored in compliance with new government regulations and electronic document discovery legal requirements? Get the New Email Archiver


Get the Access and Outlook Appointment Manager to manage all of your Outlook Calendar Appointments and Access dated information.


Happy computing,


Patrick (Pat) Wood

Gaining Access

2 Comments

  1. Posted July 7, 2009 at 7:32 AM | Permalink

    Great code. It looks like the middle of the SetServiceState has some random HTML code in there, though. Thanks for sharing.

    • Posted July 7, 2009 at 10:12 AM | Permalink

      Thanks for the compliment and I especially thank you for pointing out the code that needed to be cleaned up.


Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*