如何限制在单个Windows会话中运行的应用程序的实例数?

时间:2011-11-15 19:10:27

标签: windows excel vba

前段时间,我问过limiting the number of instances of Excel being run concurrently in Windows

感谢我在StackOverflow.com上获得的帮助,我能够将以下函数放在一起,如果已经有另一个Excel实例在运行,则会关闭所启动的任何Excel实例。

Private Function KillDuplicateProcesses() As Boolean

    Dim objWMIService As Object
    Dim colItems As Variant
    Dim objItem As Object
    Dim intCount As Integer

    Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
    Set colItems = objWMIService.InstancesOf("Win32_Process")
    For Each objItem In colItems
        intCount = intCount + Abs(LCase(objItem.Name) = "excel.exe")
        If intCount > 1 Then
            MsgBox "Excel is already running." & vbCrLf & vbCrLf & _
            "To open a file use " & IIf(Application.Version >= 12, "Office Button", "File") & " > Open (Ctrl + O).", vbCritical
            KillDuplicateProcesses = True
            Application.Quit
            Exit For
        End If
    Next

End Function

问题是,如果用户以管理员身份登录到远程桌面会话,则该用户帐户可以看到所有其他用户及其运行的进程。因此,如果另一个用户登录到同一台计算机并运行Excel,该函数也会对这些实例进行计数,并关闭刚刚启动的Excel实例。

我需要将该函数的范围限制为当前正在运行的会话。根据{{​​3}},有一个名为SessionID的类属性。我可以使用该属性并将其与当前会话的ID进行比较,以限制函数的计数,或者有更好的方法吗?

任何建议都将不胜感激。

谢谢!

以下是蒂姆建议的解决方案代码。注意我将GetOwner属性与Environ UserName和UserDomain进行比较。 Environ被认为是不可靠的,因为它可以由用户更改。

Private Function KillDuplicateProcesses() As Boolean

    Dim objWMIService As Object
    Dim colItems As Variant
    Dim objItem As Object
    Dim intCount As Integer
    Dim strProcessUser As Variant
    Dim strProcessDomain As Variant

    Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
    Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'excel.exe'")

    If colItems.Count > 1 Then

        For Each objItem In colItems

            strProcessUser = ""
            strProcessDomain = ""
            objItem.GetOwner strProcessUser, strProcessDomain
            If IsNull(strProcessUser) Then strProcessUser = ""
            If IsNull(strProcessDomain) Then strProcessDomain = ""

            intCount = intCount + Abs(strProcessUser = Environ("UserName") _
                And strProcessDomain = Environ("UserDomain"))
            If intCount > 1 Then
                MsgBox "You cannot run more than one instance of Excel while iTools is activated." & vbCrLf & vbCrLf & _
                "To open a file use " & IIf(Application.Version >= 12, "Office Button", "File") & " > Open (Ctrl + O).", vbCritical
                KillDuplicateProcesses = True
                Application.Quit
                Exit For
            End If

        Next

    End If

End Function

1 个答案:

答案 0 :(得分:2)

'get process owner username and domain
Dim strUser, strDomain
objItem.getOwner strUser, strDomain
MsgBox strUser & ", " & strDomain