2

次のサイトから次の VB スクリプトを取得しました: http://www.itninja.com/question/how-do-i-stop-start-service-in-vbscript

この VB に少し変更を加えます (関数をキャンセルします)。

この VB の目的は、サービスの制御 (サービスの停止または開始) です。

たとえば、アラートサービスを停止しようとします

また、サービスが停止しない理由がわかりませんか、それとも他の問題があるのでしょうか? VBスクリプトで?

 '//    Name:    ControlServiceWMI
 '//  Purpose:    Controls services using WMI
 '//    Input:    strComputer        - String    - the computer on which we want to       control the service. Null means local machine
 '//            strService        - String    - the name of the service. If     blank,       the    function will use strDisplayName
 '//            strDisplayName        - String    - the display name of the service.    If   blank, the function will use strService
 '//            strOperation        - String    - the operation for the service: START, STOP, PAUSE or CONTINUE
 '//            intWaitTime        - Integer    - nbr of times to loop (effectively, the nbr of seconds to wait
 '//                              for 'strOperation' to complete
  '//  Output:    strError        - String    - contains error text, if operation fails
  '//  Returns:    True/False
  '// =========================================================================================================

 Dim strComputer 
 Dim strService
 Dim strDisplayName
 Dim strOperation
 Dim intWaitTime
 Dim strError


  strComputer = pc
  strService = Alerter
  strDisplayName = Alerter
  strOperation = "STOP"
  intWaitTime = 3



'// Define WMI *state* constants        these are for the 'State' property
Const WMI_SERVICE_STOPPED                  = "Stopped"
Const WMI_SERVICE_STARTED            = "Running"
Const WMI_SERVICE_START_PENDING            = "Start Pending"
Const WMI_SERVICE_STOP_PENDING            = "Stop Pending"
Const WMI_SERVICE_RUNNING                  = "Running"
Const WMI_SERVICE_CONTINUE_PENDING        = "Continue Pending"
Const WMI_SERVICE_PAUSE_PENDING            = "Pause Pending"
Const WMI_SERVICE_PAUSED                  = "Paused"
Const WMI_SERVICE_ERROR                    = "Unknown"

'// Define WMI *status* constants        these are for the 'Status' property
Const WMI_SERVICE_OK                = "OK"
Const WMI_SERVICE_DEGRADED                = "Degraded"
Const WMI_SERVICE_UNKNOWN                  = "Unknown"
Const WMI_SERVICE_PRED_FAIL            = "Pred Fail"
Const WMI_SERVICE_STARTING                  = "Starting"
Const WMI_SERVICE_STOPPING                  = "Stopping"
Const WMI_SERVICE_SERVICE                  = "Service"    '// ?

'// Define string constants for service methods
Const START_SERVICE                    = "START"
Const STOP_SERVICE                    = "STOP"
Const PAUSE_SERVICE                    = "PAUSE"
Const CONTINUE_SERVICE                = "CONTINUE"
Const SET_AUTOMATIC                = "AUTOMATIC"
Const SET_MANUAL                = "MANUAL"
Const SET_DISABLED                = "DISABLED"

'// Win32_Service Method Return Value Table
Const WMI_Success                = 0 
Const WMI_NotSupported                = 1 
Const WMI_AccessDenied                = 2 
Const WMI_DependentServicesRunning        = 3 
Const WMI_InvalidServiceControl        = 4 
Const WMI_ServiceCannotAcceptControl        = 5 
Const WMI_ServiceNotActive            = 6 
Const WMI_ServiceRequestTimeout        = 7 
Const WMI_UnknownFailure            = 8 
Const WMI_PathNotFound                = 9 
Const WMI_ServiceAlreadyRunning        = 10
Const WMI_ServiceDatabaseLocked        = 11
Const WMI_ServiceDependencyDeleted        = 12
Const WMI_ServiceDependencyFailure        = 13
Const WMI_ServiceDisabled            = 14
Const WMI_ServiceLogonFailure            = 15
Const WMI_ServiceMarkedForDeletion        = 16
Const WMI_ServiceNoThread            = 17
Const WMI_StatusCircularDependency        = 18
Const WMI_StatusDuplicateName            = 19
Const WMI_StatusInvalidName            = 20
Const WMI_StatusInvalidParameter        = 21
Const WMI_StatusInvalidServiceAccount        = 22
Const WMI_StatusServiceExists            = 23
Const WMI_ServiceAlreadyPaused            = 24

'// Build an array of the possible return values
Dim strWMI_ReturnErrors
Dim arrWMI_ReturnErrors

strWMI_ReturnErrors                = ""
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Success,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Not Supported,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Access Denied," 
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Dependent Services Running,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Invalid Service Control,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Service Cannot Accept Control,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Service Not Active,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Service Request Timeout,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Unknown Failure,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Path Not Found,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Service Already Running,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Service Database Locked,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Service Dependency Deleted,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Service Dependency Failure,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Service Disabled,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Service Logon Failure,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Service Marked For Deletion,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Service No Thread,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Status Circular Dependency,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Status Duplicate Name,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Status Invalid Name,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Status Invalid Parameter,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Status Invalid Service Account,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Status Service Exists,"
strWMI_ReturnErrors                = strWMI_ReturnErrors & "Service Already Paused"

'// Just in case you left the trailing comma in place...
If Left(strWMI_ReturnErrors, 1) = "," Then
    strWMI_ReturnErrors    = Left(strWMI_ReturnErrors, Len(strWMI_ReturnErrors) - 1)
End If

arrWMI_ReturnErrors                = Split(strWMI_ReturnErrors, ",")

Dim strQuery
Dim objComputer
Dim objServiceList
Dim objService
Dim intCounter
Dim blnServiceReturn

ControlServiceWMI            = False

If Len(strService) = 0 And Len(strDisplayName) = 0 Then
    strMsgText            = ""
    strMsgText            = strMsgText & "Neither the service name or service display name were specified."

End If

On Error Resume Next

'// Get WMI objects and initial variables
'Set objComputer            = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objComputer            = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

If Err.Number = 0 Then
    '// Only interested in controllable services (i.e. not system services, drivers, etc)
    '// (well, we would be if ANY service set its 'AcceptStop' flag...)
    strQuery            = ""
    strQuery            = strQuery & "Select * From Win32_Service"
    strQuery            = strQuery & " Where "

    If Len(strService) > 0 Then
        strQuery        = strQuery & "Name = '" & strService & "'"
        If Len(strDisplayName) > 0 Then
            strQuery    = strQuery & " And "
            strQuery    = strQuery & "DisplayName = '" & strDisplayName & "'"
        End If
    Else
        strQuery        = strQuery & "DisplayName = '" & strDisplayName & "'"
    End If

    'strQuery            = strQuery & " And "
    'strQuery            = strQuery & "AcceptStop = True"

    Set objServiceList        = objComputer.ExecQuery (strQuery)

    If Err.Number = 0 Then
        If objServiceList.Count > 0 Then
            For Each objService in objServiceList
                '// Determine the operation and carry it out
                With objService
                    Select Case (strOperation)
                        Case SET_AUTOMATIC
                            If (.StartMode <> SET_AUTOMATIC) Then
                                Err.Number = .ChangeStartMode("Automatic")
                                If Err.Number <> 0 Then
                                    Do
                                        If .State = WMI_SERVICE_STARTED Then
                                            Exit Do
                                        End If
                                        Call Sleep(1)
                                        intCounter = intCounter + 1
                                    Loop Until intCounter = intWaitTime    '// We're only going to wait intWaitTime seconds
                                End If
                            End If

                        Case SET_MANUAL
                            If (.StartMode <> SET_MANUAL) Then
                                Err.Number = .ChangeStartMode("Manual")
                                If Err.Number <> 0 Then
                                    Do
                                        If .State = WMI_SERVICE_STARTED Then
                                            Exit Do
                                        End If
                                        Call Sleep(1)
                                        intCounter = intCounter + 1
                                    Loop Until intCounter = intWaitTime    '// We're only going to wait intWaitTime seconds
                                End If
                            End If

                        Case SET_DISABLED
                            If (.StartMode <> SET_DISABLED) Then
                                Err.Number = .ChangeStartMode("Disabled")
                                If Err.Number <> 0 Then
                                    Do
                                        If .State = WMI_SERVICE_STARTED Then
                                            Exit Do
                                        End If
                                        Call Sleep(1)
                                        intCounter = intCounter + 1
                                    Loop Until intCounter = intWaitTime    '// We're only going to wait intWaitTime seconds
                                End If
                            End If

                        Case START_SERVICE      
                            If (.State = WMI_SERVICE_STOPPED) Then
                                Err.Number = .StartService()
                                If Err.Number <> 0 Then
                                    Do
                                        If .State = WMI_SERVICE_STARTED Then
                                            Exit Do
                                        End If
                                        Call Sleep(1)
                                        intCounter = intCounter + 1
                                    Loop Until intCounter = intWaitTime    '// We're only going to wait intWaitTime seconds
                                End If
                            End If

                        Case STOP_SERVICE
                            If (.State = WMI_SERVICE_RUNNING) Or (.State = WMI_SERVICE_PAUSED) Then
                                Err.Number = .StopService()
                                If Err.Number <> 0 Then
                                    Do
                                        If .State = WMI_SERVICE_STOPPED Then
                                            Exit Do
                                        End If
                                        Call Sleep(1)
                                        intCounter = intCounter + 1
                                    Loop Until intCounter = intWaitTime    '// We're only going to wait intWaitTime seconds
                                End If
                            End If

                        Case PAUSE_SERVICE
                            If (.State = WMI_SERVICE_RUNNING) Then
                                Err.Number = .PauseService()
                                If Err.Number <> 0 Then
                                    Do
                                        If .State = WMI_SERVICE_PAUSED Then
                                            Exit Do
                                        End If
                                        Call Sleep(1)
                                        intCounter = intCounter + 1
                                    Loop Until intCounter = intWaitTime    '// We're only going to wait intWaitTime seconds
                                End If
                            End If

                        Case CONTINUE_SERVICE
                            If (.State = WMI_SERVICE_PAUSED) Then
                                Err.Number = .ContinueService()
                                If Err.Number <> 0 Then
                                    Do
                                        If .State = WMI_SERVICE_RUNNING Then
                                            Exit Do
                                        End If
                                        Call Sleep(1)
                                        intCounter = intCounter + 1
                                    Loop Until intCounter = intWaitTime    '// We're only going to wait intWaitTime seconds
                                End If
                            End If
                    End Select
                End With
            Next
        Else
            With Err
                .Description    = "The service name specified "
                .Raise 999

                If Len(strService) > 0 Then
                    If Len(strDisplayName) > 0 Then
                        .Description    = .Description & "'" & strDisplayName & "'" 
                    End If
                Else
                    .Description    = .Description & "=" & strService & "=" 
                End If

                .Description    = .Description & " does not exist." 
                .Source        = "ControlServiceWMI"
            End With
        End If
    End If
End If

If Err.Number = 0 Then
    ControlServiceWMI = True
Else
    '// Loop through the error array and, when you hit what Err.Number is,
    '// drop out and set the appropriate error text
    For intCounter = 0 To UBound(arrWMI_ReturnErrors)
        If Err.Number = intCounter Then
            Err.Description = arrWMI_ReturnErrors(intCounter)
        End If
    Next

    strMsgText = ""
    strMsgText = strMsgText & "Error " & Err.Number & " occured."

    If Len(Err.Description) > 0 Then
        strMsgText = strMsgText & Err.Description
    End If

    strError    = strMsgText
End If

On Error Goto 0



 Sub Sleep(ByVal intDelayInSecs)
'// Sleep is here because, of course, one can't use WScript.Sleep in embedded VBS CAs
Dim datStart
Dim blnTimesUp    

datStart                = Now()
blnTimesUp                = False

While Not blnTimesUp
    If DateDiff("s", datStart, Now()) >= CInt(intDelayInSecs) Then
        blnTimesUp        = True
    End If
Wend
End Sub
4

1 に答える 1

5

そのコードを捨てて、最初からやり直してください。真剣に。やりたいことがサービスの開始/停止だけの場合、そのコードをゼロから作成するよりも、そのコードを削除する方が面倒です。

service = "Alerter"

'action = "start"
action = "stop"

Set wmi = GetObject("winmgmts://./root/cimv2")

qry = "SELECT * FROM Win32_Service WHERE Name='" & service & "'"
For Each s In wmi.ExecQuery(qry)
  Select Case action
    Case "start": If s.State = "Stopped" Then s.StartService
    Case "stop" : If s.State = "Running" Then s.StopService
    Case Else   : WScript.Echo "Invalid action: " & action
  End Select
Next

サービスを再起動する場合は、各操作が完了するまで待つ必要があります。これは、操作が非同期で実行されているためです (つまり、操作がバックグラウンドで続行されている間、呼び出しはすぐに返されます)。例:

s.StopService
Do Until wmi.ExecQuery(qry & " AND State='Stopped'").Count > 0
  WScript.Sleep 100
Loop

サービスを開始する場合と同様ですが、 をチェックするだけですState='Running'

サービスがハングしているときにスクリプトが無期限にブロックされないように、そのループにタイムアウトを追加することをお勧めします。

于 2013-07-19T14:16:56.457 に答える