【发布时间】:2020-12-02 19:47:30
【问题描述】:
我正在开发一个接收会话更改通知(特别是 SessionLogon)的服务 (C#)。我通过该通知获得的唯一信息是SessionId。
我的最终目标是检查登录用户的配置文件(本地/漫游 AppData/MyCorp/MyApp 文件夹)是否有特定设置,如果存在则执行任务。
我需要从 SessionId 转到我可以映射到本地用户配置文件的东西,或者直接映射到 用户帐户 SID 或映射到可以映射到SID,(例如 "
我在 SO 上找到的解决方案依赖于 Windows 终端服务 (WTS) API(例如 WTSQuerySessionInformation),但远程桌面服务在 Windows 10 家庭版中不可用,所以这是一个非首发。
有谁知道如何从 SessionId 映射到不涉及 WTS API 的本地用户帐户?
(编辑#1)澄清:
在 .NET 中,ServiceBase 类有一个 OnSessionChange 覆盖,用于登录/注销/解锁/锁定事件。我最初认为这是针对所有此类事件(来自物理机或终端服务器)。
看起来这个仅适用于终端服务器会话(?)所以,显然,我得到的sessionId 是终端服务器特定的东西。正如@RbMm 在下面指出的那样,这个覆盖可能不会在 Windows Home 版上被首先调用。不过,这是一个有争议的问题,因为我感兴趣的是本地(物理)登录事件,这与终端服务会话完全不同。
在我看来,服务基类会有这样一个有用的事件,但它与 Terminal Services 相关联,而不是适用于所有情况,这对我来说似乎很奇怪。也许有人对此有所了解?
(编辑#2)实现:
@RbMm 的 cmets 消除了我一开始的一些误解。这是更新:
- OnSessionChange 事件仅用于终端服务,与本地(物理)登录会话无关(我将两者混为一谈)。
- 我只对本地登录会话感兴趣,因此我将寻找一种方法来在我的服务中获得有关它们的通知。如果没有此类通知,我将不得不设置一个计时器并进行投票。
- 我需要从收到的任何信息以及此类通知(或定期致电
LsaGetLogonSessionData)中获取用户帐户 SID
【问题讨论】:
-
如果远程桌面服务不可用或未运行 - 根本不会更改会话。结果没有通知,在这种情况下你永远不会打电话给
WTSQuerySessionInformationW。从另一边这个 api 总是被导出,所以你总是可以导入它 -
我也认为文档非常糟糕且不正确。 如果远程桌面服务未运行,则对 WTSQuerySessionInformation 的调用失败 - 不清楚这仅用于检索会话 ID 或任何情况。但在我的系统上,远程桌面服务 (TermService) 没有运行,但
WTSQuerySessionInformation不会失败 并返回实际信息 -
OnSessionChange- 我如何理解您准确注册终端会话通知。不是登录会话。这里你得到WM_WTSSESSION_CHANGE消息的wParam参数和指向WTSSESSION_NOTIFICATION的指针。所以你需要准确地打电话给WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSSessionInfo, (PWSTR*)&pp, &dwSessionId),我确定这个电话不会失败。 -
我认为您不了解终端和登录会话之间的区别。在单个终端会话中可以有几个不同的登录会话。例如运行this 看看输出
-
注册
SERVICE_ACCEPT_SESSIONCHANGE时无论如何服务都会收到SERVICE_CONTROL_SESSIONCHANGE通知。它在用户登录,注销,锁定,解锁......等本地用户时调用,不仅适用于远程用户。如果本地用户WinStationName将是 Console
标签: c# windows winapi windows-10 windows-identity