2013-07-19 66 views
1

我採取了以下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

將代碼扔掉並重新開始。認真。如果您只想開始/停止服務,那麼剝離該代碼比從頭開始編寫代碼更麻煩。

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'

在該循環中添加超時值可能是一個好主意,以便在服務掛起時腳本不會無限期地被阻塞。

+0

但我確實停止並開始瞭解代碼是否知道服務是否已停止?我重新啓動之前? ,我的目標是重新啓動服務,(睡眠不是解決方案,因爲一些服務需要分配時間來啓動/停止) – maihabunash

+0

代碼中缺少某些東西(我得到錯誤對象所需的) – maihabunash

+1

第二個代碼片段不會運行通過它自己。您需要將其從第一個片段集成到循環中。如果您無法使用它:使用您當前的代碼更新您的問題。 –