将SessionId转换为用户帐户SID _without_ WTSQuerySessionInformation?

问题描述

我正在使用一种接收会话更改通知(特别是SessionLogon)的服务(C#)。我通过该通知获得的唯一信息是SessionId

我的最终目标是检查登录用户的个人资料(本地/漫游AppData / MyCorp / MyApp文件夹)中的特定设置,并执行任务(如果有)。

我需要从 SessionId 转到我可以映射到本地用户个人资料的内容,或者直接到 User Account SID 或可以映射到SID(例如“ \ ” 等)。

我在SO上找到的解决方案取决于Windows终端服务(WTS)API(例如WTSQuerySessionInformation),但是远程桌面服务在Windows 10家庭版上不可用,所以那是个初学者。

有人知道如何从 SessionId 映射到不涉及WTS API的本地用户帐户吗?

(编辑#1)澄清:

在.NET中,ServiceBase类具有OnSessionChange覆盖,该覆盖被调用以用于登录/注销/解锁/锁定事件。我原本以为这是针对所有这样的事件(来自物理机或终端服务器)。

看起来这只 适用于终端服务器会话(?)因此,显然,我得到的sessionId是终端服务器特定的东西。正如@RbMm在下面指出的那样,Windows Home Edition可能不会首先调用此覆盖。不过,这是有争议的,因为这是我感兴趣的本地(物理)登录事件,并且与终端服务会话完全不同。

在我看来,服务基类会有这样的有用事件,但将其与 Terminal Services 绑定在一起,而不是在所有情况下都有效。也许有人对此有所了解?

(编辑#2)实现:

@RbMm的评论消除了我开始时的一些误解。这是更新:

  • OnSessionChange事件对于终端服务来说仅是 ,与本地(物理)登录会话无关(我将二者混为一谈)。
  • 我只对本地登录会话感兴趣,因此我将在我的服务中寻找一种方法来获取有关 them 的通知。如果没有此类通知,我将必须设置一个计时器并进行轮询。
  • 我需要从我收到的任何信息以及此类通知(或定期调用LsaGetLogonSessionData)中得出用户帐户SID

解决方法

我认为您可以通过WMI检索此信息

Win32_LogonSession

class Win32_LogonSession : Win32_Session
{
  string   Caption;
  string   Description;
  datetime InstallDate;
  string   Name;
  string   Status;
  datetime StartTime;
  string   AuthenticationPackage;
  string   LogonId;
  uint32   LogonType;
};

此外:

LogonId

数据类型:字符串

访问类型:只读

预选赛:键

分配给登录会话的ID。

示例

var scope = new ManagementScope(ManagementPath.DefaultPath);
var query = new SelectQuery($"Select * from Win32_LogonSession where LogonId = {SessionId}");
var searcher = new ManagementObjectSearcher(scope,query);
var results = searcher.Get();
foreach (ManagementObject mo in results)
{
 
}

请注意,这完全未经测试

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...