4

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

代理单击程序图标 --> progcheck.vbs 的批处理文件调用 -->

progcheck.vbs 看起来是“whatever.exe”仅在该用户下运行-->

如果程序在该用户下运行,则 MsgBox "Program running" --> wscript.quit (这需要从批处理文件中终止)

else --> 返回批处理文件。

我已经在批处理文件中使用 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

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

4

2 回答 2

7

更新的代码 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

那应该这样做。

额外的

要显示每个正在运行的进程,只需运行:

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
于 2013-10-12T02:38:49.250 回答
0

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

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

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
于 2019-10-29T12:24:50.277 回答