检查已启动的程序时出现“无效请求”错误

时间:2014-12-30 12:41:16

标签: vbscript wmi-query

我想编写一个程序,如果启动的程序数量(toto1.bat,toto2.bat,toto3.bat,iexplore.exe等)每15分钟检查一次,是否找不到任何内容,以便启动它。

我的草稿脚本试图达到我的目标,但我在第31行有一个“无效请求”错误。

Option Explicit
Dim ProcessPath1,ProcessPath2,ProcessPath3,ProcessPath4
ProcessPath1 = "c:\toto1.bat"
ProcessPath2 = "c:\toto2.bat"
ProcessPath3 = "c:\toto3.bat"
ProcessPath4 = "%ProgramFiles%\Internet Explorer\iexplore.exe"
'Quitter si le script est déjà lancé
'If AppPrevInstance() = True Then WScript.Quit
'**************************************************************************
'Une boucle Do...Loop avec une pause de 15 minutes
Do
    Call CheckProcess(DblQuote(ProcessPath4))
    Call CheckProcess(DblQuote(ProcessPath1))
    Call CheckProcess(DblQuote(ProcessPath2))
    Call CheckProcess(DblQuote(ProcessPath3))
    Call Pause(15) 'Pause de 15 minutes
Loop
'**************************************************************************
Sub CheckProcess(ProcessPath)
    Dim strComputer,objWMIService,colProcesses,WshShell,Tab,ProcessName,MyCommandLine
    strComputer = "."
    Tab = Split(ProcessPath,"\")
    ProcessName = Tab(UBound(Tab))
    ProcessName = Replace(ProcessName,Chr(34),"")
    MyCommandLine = "cmd /c "& DblQuote(ProcessPath) &""
    MsgBox "ProcessName : " & ProcessName & vbCrLf & "CommandLine : " _
        & MyCommandLine,vbInformation,"CheckProces"
    Set objWMIService = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    Set colProcesses = objWMIService.ExecQuery _
        ("Select * from Win32_Process Where Name like '%" & ProcessName _
        & "%' or CommandLine like '%" & MyCommandLine & "%'")
    If colProcesses.Count = 0 Then
        Set WshShell = CreateObject("WScript.Shell")
        WshShell.Run ProcessPath
    Else
        Exit Sub
    End if
End Sub
'**************************************************************************
'Fonction pour ajouter les doubles quotes dans une variable
Function DblQuote(Str)
    DblQuote = Chr(34) & Str & Chr(34)
End Function
'**************************************************************************
Sub Pause(NMinutes)
    Wscript.Sleep(NMinutes*1000*60)
End Sub
'**************************************************************************
Function AppPrevInstance()
    'Vérifie si un script portant le même nom que le présent script est déjà
    'lancé
    Dim strComputer,objWMIService,colScript,objScript,RunningScriptName,Counter
    strComputer = "."
    Counter = 0
    Set objWMIService = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    Set ColScript = objWMIService.ExecQuery _
        ("SELECT * FROM Win32_Process WHERE Name = 'Wscript.exe' OR Name = 'Cscript.exe'")
    For Each objScript In colScript
        RunningScriptName = Mid(objScript.CommandLine, _
            InstrRev(objScript.CommandLine, "\", -1, 1) + 1, _
            Len(objScript.CommandLine) - InstrRev(objScript.CommandLine, "\", -1, 1) - 2)
        If WScript.ScriptName = RunningScriptName Then Counter = Counter + 1
        Wscript.Sleep 10000
    Next
    If Counter > 1 Then
        AppPrevInstance = True
    Else
        AppPrevInstance = False
    End If
    Set colScript = Nothing
    Set objWMIService = Nothing
End Function
'**************************************************************************

2 个答案:

答案 0 :(得分:2)

MyCommandLine包含反斜杠,它们是WMI查询中的转义字符。路径中未转义的反斜杠使查询无效,从而导致您观察到的错误。

替换

MyCommandLine = "cmd /c "& DblQuote(ProcessPath) &""

MyCommandLine = "cmd /c "& DblQuote(Replace(ProcessPath, "\", "\\")) &""

答案 1 :(得分:1)

我解决了这个问题:

Option Explicit
If AppPrevInstance() Then   
    MsgBox "Il y a une instance déjà en cours",VbExclamation,"Il y a une instance déjà en cours"    
    WScript.Quit   
Else   
    Do   
        Call Main(Array("c:\toto1.bat","c:\toto2.bat","c:\toto3.bat","%ProgramFiles%\Internet Explorer\iexplore.exe"))
        Call Pause(15) 'Pause de 15 minutes
    Loop   
End If   
'**************************************************************************
Sub Main(colProcessPaths)   
    Dim ProcessPath   
    For Each ProcessPath In colProcessPaths     
        CheckProcess(ProcessPath)   
    Next   
End Sub   
'**************************************************************************
Sub CheckProcess(ProcessPath)   
    Dim ProcessName : ProcessName = StripProcPath(ProcessPath)   
    With GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")   
        With .ExecQuery("SELECT * FROM Win32_Process WHERE Commandline LIKE " &  CommandLineLike(ProcessName))      
            If .Count = 0 Then    
                With CreateObject("WScript.Shell")  
                    .Run DblQuote(ProcessPath) 
                End With    
            Else    
                Exit Sub    
            End if   
        End With   
    End With   
End Sub   
'**************************************************************************
Function AppPrevInstance()   
    With GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")   
        With .ExecQuery("SELECT * FROM Win32_Process WHERE CommandLine LIKE " & CommandLineLike(WScript.ScriptFullName) & _
        " AND CommandLine LIKE '%WScript%' OR CommandLine LIKE '%cscript%'")   
            AppPrevInstance = (.Count > 1)   
        End With   
    End With   
End Function   
'**************************************************************************
Sub Pause(Minutes)    
    Wscript.Sleep(Minutes*1000*60)    
End Sub   
'**************************************************************************
Function StripProcPath(ProcessPath)   
    Dim arrStr : arrStr = Split(ProcessPath, "\")   
    StripProcPath = arrStr(UBound(arrStr))   
End Function   
'**************************************************************************
Function CommandLineLike(ProcessPath)   
    ProcessPath = Replace(ProcessPath, "\", "\\")   
    CommandLineLike = "'%" & ProcessPath & "%'"   
End Function
'**************************************************************************
'Fonction pour ajouter les doubles quotes dans une variable
Function DblQuote(Str)
    DblQuote = Chr(34) & Str & Chr(34)
End Function
'**************************************************************************