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

标签 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

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

我需要将该函数的范围限制在当前运行的 session 中。根据MSDN documentation有一个名为 SessionID 的类属性。我可以使用该属性并将其与当前 session 的 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

最佳答案

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

关于windows - 如何限制在单个 Windows session 中运行的应用程序的实例数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8141761/

相关文章:

excel - 需要帮助在单个单元格中获取多个值,并在 excel 中满足条件

vba - 如何创建动态变量名VBA

c - 在 Windows 上,C 的二进制写入模式出错?

c# - 如何自动调整 RDLC 报告中的列宽

java - 在 Windows 和 Snow Leopard 机器之间使用 Java 应用程序时遇到问题

excel - 无法正确获取自定义函数语法 : Contains()

events - 如何使用Excel VBA制作外部日志?

windows - 当某些字段为空时,Windows 批处理文件如何从带分隔符的文本文件中正确读取数据?

excel - 如何防止matlab自动将带有逗号的字符串分隔到csv中的不同单元格?

excel - 使用 Excel 宏从 SAP 提取数据