如何在Windows中获取当前的交互式用户会话数? [英] How to get the current number of interactive user sessions in Windows?
问题描述
我正在编写Windows服务,该服务需要知道计算机上当前是否有任何用户登录.
I'm writing a Windows service that needs to know whether there are any users currently logged-on in the machine.
到目前为止,我已经尝试过Win32_LogonSession
(WMI)和LsaEnumerateLogonSessions
/LsaGetLogonSessionData
(secur32.dll).
So far I've tried Win32_LogonSession
(WMI), and LsaEnumerateLogonSessions
/LsaGetLogonSessionData
(secur32.dll).
两者都能工作,并且似乎返回相同的数据,但是当用户注销时它们更新太慢:
Both work, and seem to return the same data, but they are too slow to update when a user log off:
- 系统启动时,他们返回"0个交互式用户". (确定)
- 当我登录时,他们返回"1个交互式用户". (确定)
- 但是当我注销时,用户数保持为1.重新登录后,用户数为2,依此类推.
因此Win32_LogonSession或LsaEnumerateLogonSessions都足够好. 该服务需要在最后一个互动用户离开后的5分钟内知道.
Thus Win32_LogonSession nor LsaEnumerateLogonSessions are good enough. The service needs to know within 5 minutes after the last interactive user leaves.
SysInternals的LogonSessions.exe甚至都没有提供最新的答案.
另外,答案不能是监视器登录和注销事件并具有计数器变量",因为该服务可以随时启动.
Not even SysInternals' LogonSessions.exe gives up-to-date answers.
Also, the answer cannot be "monitor logon and logoff events and have a counter variable", because the service can be started at any time.
推荐答案
我最终采用了以下方法:计算至少运行一个进程的交互式会话的数量.
I ended up with the following approach: count the number of interactive sessions which have at least one process running.
- LsaEnumerateLogonSessions(secur32.dll)
- LsaGetLogonSessionData(secur32.dll)
- sessionData .LogonType=
- LsaEnumerateLogonSessions (secur32.dll)
- LsaGetLogonSessionData (secur32.dll)
- sessionData.LogonType = SECURITY_LOGON_TYPE.Interactive or sessionData.LogonType = SECURITY_LOGON_TYPE.RemoteInteractive
- sessionData.LoginID <- Keep this value in a LUID set.
- LsaFreeReturnBuffer (secur32.dll)
[首先,我们需要为当前应用程序启用SeDebugPrivilege.]
[First we need to enable the SeDebugPrivilege to the current application.]
- GetCurrentProcess(kernel32.dll)
- OpenProcessToken TOKEN_ADJUST_PRIVILEGES (advapi32.dll)
- LookupPrivilegeValue SE_DEBUG_NAME (advapi32.dll)
- AdjustTokenPrivileges(advapi32.dll)
- CloseHandle(kernel32.dll)
- GetCurrentProcess (kernel32.dll)
- OpenProcessToken TOKEN_ADJUST_PRIVILEGES (advapi32.dll)
- LookupPrivilegeValue SE_DEBUG_NAME (advapi32.dll)
- AdjustTokenPrivileges (advapi32.dll)
- CloseHandle (kernel32.dll)
[然后检索我们想要的数据.]
[Then retrieve the data we want.]
- EnumProcesses(psapi.dll)
- OpenProcess PROCESS_QUERY_INFORMATION (kernel32.dll)
- OpenProcessToken 令牌查询(advapi32.dll)
- GetTokenInformation TOKEN_INFORMATION_CLASS.TokenStatistics (advapi32.dll)
- accessTokenStatistics .AuthenticationId <-将此值保存在LUID集中.
- CloseHandle(kernel32.dll)
- EnumProcesses (psapi.dll)
- OpenProcess PROCESS_QUERY_INFORMATION (kernel32.dll)
- OpenProcessToken TOKEN_QUERY (advapi32.dll)
- GetTokenInformation TOKEN_INFORMATION_CLASS.TokenStatistics (advapi32.dll)
- accessTokenStatistics.AuthenticationId <- Keep this value in a LUID set.
- CloseHandle (kernel32.dll)
interactiveSessionsCount = | { sessionData.LoginID } ∩ { accessTokenStatistics.AuthenticationId } |
提示:sessionData.LoginID和accessTokenStatistics.AuthenticationId均为 LUID类型.
Obs: sessionData.LoginID and accessTokenStatistics.AuthenticationId are both of type LUID.
这篇关于如何在Windows中获取当前的交互式用户会话数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!