windows - 如何在 Windows 中获取当前的交互式用户 session 数?

标签 windows winapi language-agnostic windows-services

我正在编写一个 Windows 服务,它需要知道当前是否有任何用户在机器上登录。

到目前为止,我已经尝试过 Win32_LogonSession (WMI) 和 LsaEnumerateLogonSessions/LsaGetLogonSessionData (secur32.dll)。

两者都有效,并且似乎返回相同的数据,但是当用户注销时它们更新速度太慢:

  • 当系统启动时,他们返回“0 个交互用户”。 (好的)
  • 当我登录时,他们返回“1 个交互式用户”。 (好的)
  • 但是当我注销时,用户数保持为 1。重新登录后,用户数为 2,依此类推。

因此 Win32_LogonSession 和 LsaEnumerateLogonSessions 都足够好。 服务需要在最后一个交互用户离开后 5 分钟内知道。

甚至 SysInternals 的 LogonSessions.exe 也没有给出最新的答案。
此外,答案不能是“监视登录和注销事件并具有计数器变量”,因为服务可以随时启动。

最佳答案

我最终采用了以下方法:计算至少有一个进程在运行的交互式 session 的数量。

1) 获取每个交互 session 的登录 session ID。

  • LsaEnumerateLogonSessions (secur32.dll)
  • LsaGetLogonSessionData (secur32.dll)
  • sessionData .LogonType = SECURITY_LOGON_TYPE.Interactive或 sessionData.LogonType = SECURITY_LOGON_TYPE.RemoteInteractive
  • sessionData.LoginID <- 将此值保存在 LUID 集中。
  • LsaFreeReturnBuffer (secur32.dll)

2) 获取每个正在运行的进程的登录 session ID。

[首先我们需要为当前应用启用SeDebugPrivilege。]

  • GetCurrentProcess (kernel32.dll)
  • OpenProcessToken TOKEN_ADJUST_PRIVILEGES (advapi32.dll)
  • LookupPrivilegeValue SE_DEBUG_NAME (advapi32.dll)
  • AdjustTokenPrivileges (advapi32.dll)
  • 关闭句柄 (kernel32.dll)

[然后检索我们想要的数据。]

3) 设置交集基数

interactiveSessionsCount = | { sessionData.LoginID } ∩ { accessTokenStatistics.AuthenticationId } |

观察:sessionData.LoginID 和 accessTokenStatistics.AuthenticationId 都是 LUID 类型.

关于windows - 如何在 Windows 中获取当前的交互式用户 session 数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6255424/

相关文章:

c++ - 无法在任何其他机器上运行 Windows 应用程序

c++ - 使用 C++ Win32 API 启用视觉样式?

.net - 是否有可用于 .NET 的完整 user32.dll 包装器库?

language-agnostic - 在散点列表中查找路径的算法

oop - 只写属性有实际应用吗?

database - 什么是存储这种关系的好方法,以便我可以有效地回答这种形式的查询?

windows - 使用 TopShelf,我在 "Topshelf.HostConfigurators.WindowsServiceDescription service has not been installed yet."附近遇到错误

windows - Windows 的 R 环境中的自动换行

用于确定服务包版本的 Windows API

c++ - 在客户区外绘图,winAPI