2

我正在编写一个服务应用程序,它需要枚举所有当前用户会话,并获取他们的会话 ID,然后查看哪些进程正在为哪些会话运行。我正在使用WTSEnumerateSessions()API,以及WTSQuerySessionInformation()获取会话特定信息。不幸的是,那些 WTS API 非常不可靠。

在关闭快速用户切换的 Windows XP 机器上,或在加入域的 XP 机器上,这些 API 不会立即可用。RPC_S_INVALID_BINDING在 Windows XP 启动并且我的服务启动后的几分钟内,它们可能会失败并显示错误代码或 1702。

我找不到任何官方文档来解释如何处理这种限制。通过搜索引擎可用的方法是等待终端服务服务加载,这当然是可能的,但在 a** 实施中成为主要的痛点。

因此,如果有人可以回答以下问题,我将不胜感激:

  1. 是否有任何替代 API 可以处理特定于会话的数据,比那些 WTS 更可靠?我主要需要查看机器上的当前会话,获取用户名和会话状态。还要为每个进程枚举具有会话 ID 的进程。(我知道这是可能的,因为 GINA 或登录屏幕可以在终端服务加载之前完成所有这些操作。)
  2. 在我的服务在任何版本的 Windows Vista/Windows 7 机器上启动之前WTSEnumerateSessions(),是否 100% 保证 WTS 类 API(例如WTSQuerySessionInformation()WTSEnumerateProcesses())会加载?

请注意bofore任何非常重要的规定。

4

3 回答 3

4

另一个可能对您有帮助的 API 是具有字段的LsaEnumerateLogonSessionsLsaGetLogonSessionData SECURITY_LOGON_SESSION_DATA 。Session请参阅代码示例这个。要获取有关进程会话的信息,您可以使用GetTokenInformation作为TokenSessionId参数。要枚举进程,您可以使用NtQuerySystemInformation(请参阅我的旧答案)。

于 2011-10-28T23:19:09.247 回答
3

这里建议了一些解决方案。总之:

  1. 确保“TermSrv”正在运行(通过依赖、手动启动/等待它等)。
  2. 等待设置“Global\TermSrvReadyEvent”事件。
于 2011-10-28T23:16:20.423 回答
1

我认为您询问的 #2 在 Vista/7 上得到保证,因为这些 API 需要在任何大于 0 的会话上创建任何进程。

于 2011-10-28T23:28:18.620 回答