将SessionId转换为用户帐户SID(_W不包含WTSQuerySessionInformation)



我正在开发一个接收会话更改通知(特别是SessionLogon(的服务(C#(。我从该通知中得到的唯一信息是SessionId

我的最终目标是检查登录用户的配置文件(本地/漫游AppData/MyCorp/MyApp文件夹(中的特定设置,并在那里执行任务。

我需要从SessionId转到可以映射到本地用户配置文件的东西,可以直接映射到用户帐户SID,也可以映射到可以映射到SID的东西(例如<domain>\<username><等(。

我在SO上找到的解决方案依赖于Windows终端服务(WTS(API(例如WTSQuerySessionInformation(,但远程桌面服务在Windows 10 Home edition上不可用,所以这不是入门级的。

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

(编辑#1(澄清:

在.NET中,ServiceBase类有一个OnSessionChange覆盖,用于登录/注销/解锁/锁定事件。我最初认为这是针对所有此类事件(来自物理机器或终端服务器(。

看起来这个只适用于终端服务器会话(?(所以,很明显,我得到的sessionId是特定于终端服务器的东西。正如@RbMm在下面指出的那样,在Windows Home edition上,这种覆盖可能一开始就不会被调用。不过,这是一个没有意义的问题,因为这是我感兴趣的本地(物理(登录事件,与终端服务会话完全不同。

服务基类会有这样一个有用的事件,但却将其绑定到终端服务,而不是适用于所有情况,这对我来说似乎很奇怪。也许有人对此有所了解?

(编辑#2(实现:

@RbMm的评论澄清了我一开始的一些误解。更新如下:

  • OnSessionChange事件仅适用于终端服务,与本地(物理(登录会话无关(我将两者混为一谈(
  • 我只对本地登录会话感兴趣,所以我会想办法在我的服务中获得关于它们的通知。如果没有这样的通知,我将不得不设置一个计时器和轮询
  • 我需要从我收到的任何信息以及这样的通知(或定期调用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)
{

}

请注意,这是完全未经测试的

您可以通过进程而不是令牌来解析此信息。我这里没有c#示例,但这里有演示概念的PS片段:

# https://learn.microsoft.com/en-us/windows/win32/devnotes/getting-the-active-console-session-id
$sessionId = [System.Runtime.InteropServices.Marshal]::ReadByte(0x7ffe02d8)
$pList = (Get-CimInstance Win32_Process -Filter "name = 'explorer.exe' and SessionId=$sessionId")
$winEx = $pList | where {$_.Path -eq 'C:WINDOWSexplorer.exe'} | sort CreationDate | select -First 1
$sid = (Invoke-CimMethod -InputObject $winEx -MethodName GetOwnerSid).sid

最新更新