VBScript用于检查用户的打开过程

时间:2013-10-12 00:00:46

标签: batch-file vbscript process wmi

我需要一个VBScript来检查特定用户是否正在使用某个进程:

代理点击计划图标 - >批处理文件调用progcheck.vbs - >

progcheck.vbs看起来只是在那个用户下运行“whatever.exe” - >

如果程序在该用户下运行,那么MsgBox“程序运行” - > wscript.quit(这需要终止批处理文件)

其他 - >返回批处理文件。

我在批处理文件中尝试使用tasklist并且脚本可以正常工作,但是对于域用户来说需要永远运行。想要在vbscript中这样做。

*** 使用MODS 10/12更新的脚本 ** * **

OPTION EXPLICIT

    DIM strComputer,strProcess, strUserName,wshShell

    Set wshShell = WScript.CreateObject( "WScript.Shell" )
    strUserName = wshShell.ExpandEnvironmentStrings( "%USERNAME%" )

    strComputer = "." ' 
    strProcess = "notepad.exe"


    IF isProcessRunning(strComputer,strProcess,strUserName) THEN
            If MsgBox ("Notepad needs to be closed.", 1) = 1 then
                wscript.Quit(1)
            End If
    END IF

FUNCTION isProcessRunning(BYVAL strComputer,BYVAL strProcessName,BYVAL strUserName)

    DIM objWMIService, strWMIQuery

    strWMIQuery = "Select * from Win32_Process where name like '" & strProcessName & "' AND owner like '" &strUserName& "'" 

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


    IF objWMIService.ExecQuery(strWMIQuery).Count > 0 THEN
        isProcessRunning = TRUE
    ELSE
        isProcessRunning = FALSE
    END If

End Function

让我知道你的想法以及我错在哪里。提前谢谢。

2 个答案:

答案 0 :(得分:6)

更新后的代码v3:审核求助意见

OPTION EXPLICIT

    DIM strComputer, strProcess, strUserName, wshShell

    Set wshShell = WScript.CreateObject( "WScript.Shell" )
    strUserName = wshShell.ExpandEnvironmentStrings( "%USERNAME%" )
    strComputer = "."
    strProcess = "notepad.exe" 'change this to whatever you are trying to detect

    IF isProcessRunning(strComputer, strProcess, strUserName) THEN
        If MsgBox ("Notepad needs to be closed.", 1) = 1 then
            wscript.Quit(1) 'you need to terminate the process if that's your intention before quitting
        End If
    Else
        msgbox ("Process is not running") 'optional for debug, you can remove this
    END IF

FUNCTION isProcessRunning(ByRef strComputer, ByRef strProcess, ByRef strUserName)

    DIM objWMIService, strWMIQuery, objProcess, strOwner, Response

    strWMIQuery = "SELECT * FROM Win32_Process WHERE NAME = '" & strProcess & "'"

    SET objWMIService = GETOBJECT("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2").ExecQuery(strWMIQuery)

    IF objWMIService.Count > 0 THEN
        msgbox "We have at least ONE instance of Notepad"
        For Each objProcess in objWMIService
            Response = objProcess.GetOwner(strOwner)
            If Response <> 0 Then
                'we didn't get any owner information - maybe not permitted by current user to ask for it
                Wscript.Echo "Could not get owner info for process [" & objProcess.Name & "]" & VBNewLine & "Error: " & Return
            Else 
                Wscript.Echo "Process [" & objProcess.Name & "] is owned by [" & strOwner & "]" 'for debug you can remove it
                if strUserName = strOwner Then
                    msgbox "we have the user who is running notepad"
                    isProcessRunning = TRUE
                Else
                    'do nothing as you only want to detect the current user running it
                    isProcessRunning = FALSE
                End If
            End If
        Next
    ELSE
        msgbox "We have NO instance of Notepad - Username is Irrelevant"
        isProcessRunning = FALSE
    END If

End Function

您可以使用以下功能:

FUNCTION isProcessRunning(BYVAL strComputer,BYVAL strProcessName)

    DIM objWMIService, strWMIQuery

    strWMIQuery = "Select * from Win32_Process where name like '" & strProcessName & "'"

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


    IF objWMIService.ExecQuery(strWMIQuery).Count > 0 THEN
        isProcessRunning = TRUE
    ELSE
        isProcessRunning = FALSE
    END IF

END FUNCTION

对于本地计算机,您可以使用"."

对于进程名称,您将使用可执行文件"notepad.exe"

对于其余代码,您可以使用简单的东西:

OPTION EXPLICIT
DIM strComputer,strProcess

strComputer = "." ' local computer
strProcess = "notepad.exe" 'whatever is the executable

IF isProcessRunning(strComputer,strProcess) THEN
    'do something
ELSE
    'do something else or nothing
    wscript.echo strProcess & " is NOT running on computer '" & strComputer & "'"
END IF

应该这样做。

<强> EXTRA

要显示每个进程都在运行,请运行:

Option Explicit
Dim objWMIService, objProcess, colProcess
Dim strComputer, strList

strComputer = "."

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

Set colProcess = objWMIService.ExecQuery _
("Select * from Win32_Process")

For Each objProcess in colProcess
    strList = strList & vbCr & _
    objProcess.Name
Next

WSCript.Echo strList
WScript.Quit

答案 1 :(得分:0)

在终端服务器中,此功能可能非常慢,所有GetOwner调用的性能都非常糟糕。

我创建的

非常快 解决方案是使用当前用户的SessionID来缩小查询范围(假设我们只需要当前用户的进程),所以我添加了以下代码: / p>

SessionID可以通过以下方式获取:

Dim oExec, sOutput, iUserPos, iUserLen, iStatePos, SessionID
dim oShell, userName

Set oShell = CreateObject("Wscript.Shell")
userName = oShell.ExpandEnvironmentStrings("%USERNAME%")

Set oExec = oShell.Exec("query session %username%")
sOutput = LCase(oExec.StdOut.ReadAll)
iUserPos = InStr(sOutput, LCase(userName))
iStatePos = InStr(sOutput, "active")
iUserLen = Len(userName)

SessionID = CInt(Trim(Mid(sOutput, iUserPos+iUserLen, iStatePos-iUserPos-iUserLen)))

更改了上一篇文章的功能:

Function isProcessRunning(ByRef strComputer, ByRef strProcess, ByRef strUserName, byRef sessionID)
    DIM objWMIService, strWMIQuery, objProcess, strOwner, Response

    strWMIQuery = "SELECT * FROM Win32_Process WHERE SessionId = " & sessionID & " And NAME = '" & strProcess & "'"

    SET objWMIService = GETOBJECT("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2").ExecQuery(strWMIQuery)

    IF objWMIService.Count > 0 THEN
        'msgbox "We have at least ONE instance of Notepad"
        For Each objProcess in objWMIService
            Response = objProcess.GetOwner(strOwner)
            If Response = 0 Then
                'Wscript.Echo "Process [" & objProcess.Name & "] is owned by [" & strOwner & "]" 'for debug you can remove it
                if strUserName = strOwner Then
                    'msgbox "we have the user who is running notepad"
                    isProcessRunning = TRUE
                Else
                    'do nothing as you only want to detect the current user running it
                    isProcessRunning = FALSE
                End If
                'else 
                 'we didn't get any owner information - maybe not permitted by current user to ask for it
                 'Wscript.Echo "Could not get owner info for process [" & objProcess.Name & "]" & VBNewLine & "Error: " & Return
            End If
        Next
    ELSE
        'msgbox "We have NO instance of Notepad - Username is Irrelevant"
        isProcessRunning = FALSE
    END If

End Function