You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中区分同一客户端连接Windows Server的并发RDC用户

没问题!在Windows Server的多会话RDP场景下,%CLIENTNAME%确实会因为客户端机器相同而无法区分不同会话的用户,这里给你几个在C#里可靠区分他们的方案:

方法1:利用唯一的会话ID(Session ID)

每个RDP用户会话都会被分配一个唯一的整数会话ID,哪怕是同一台客户端机器的多个并发会话,这个ID也不会重复。你可以直接获取当前进程所在的会话ID,或者查询系统中所有活跃的会话信息:

using System.Diagnostics;

// 获取当前进程所属的会话ID
int currentSessionId = Process.GetCurrentProcess().SessionId;
Console.WriteLine($"当前用户会话ID: {currentSessionId}");

如果需要遍历所有会话并关联用户信息,还可以结合Windows API来实现,比如下面用WTS API获取指定会话的用户名:

using System;
using System.Runtime.InteropServices;

public static class SessionHelper
{
    [DllImport("wtsapi32.dll")]
    private static extern bool WTSQuerySessionInformation(IntPtr hServer, int sessionId, WTS_INFO_CLASS infoClass, out IntPtr ppBuffer, out int pBytesReturned);

    [DllImport("wtsapi32.dll")]
    private static extern void WTSFreeMemory(IntPtr pMemory);

    private enum WTS_INFO_CLASS
    {
        WTSUserName = 5,
        WTSClientName = 7
    }

    public static string GetSessionUserName(int sessionId)
    {
        IntPtr buffer = IntPtr.Zero;
        int bytesReturned;
        
        if (WTSQuerySessionInformation(IntPtr.Zero, sessionId, WTS_INFO_CLASS.WTSUserName, out buffer, out bytesReturned) && buffer != IntPtr.Zero)
        {
            try
            {
                return Marshal.PtrToStringAnsi(buffer);
            }
            finally
            {
                WTSFreeMemory(buffer);
            }
        }
        return string.Empty;
    }
}

// 调用示例
string userName = SessionHelper.GetSessionUserName(Process.GetCurrentProcess().SessionId);
Console.WriteLine($"当前会话的用户名: {userName}");
方法2:获取用户的安全标识符(SID)

如果你的场景是区分不同用户(而非同一用户的多个会话),那么每个用户账户的SID是全局唯一的,完全可以用来做区分:

using System.Security.Principal;

// 获取当前用户的SID字符串
string userSid = WindowsIdentity.GetCurrent().User.Value;
Console.WriteLine($"当前用户SID: {userSid}");

这个方法的好处是简单直接,不需要依赖会话相关的API,但如果是同一用户开了多个RDP会话,SID会相同,这时候就需要结合会话ID一起使用。

方法3:通过WMI查询完整的会话信息

WMI提供了丰富的系统会话查询能力,你可以一次性获取所有活跃会话的ID、用户名、客户端名称等信息,方便做批量区分:

using System.Management;

// 查询所有活跃的终端服务会话
var sessionSearcher = new ManagementObjectSearcher("SELECT SessionId, UserName, ClientName FROM Win32_TerminalServiceSession WHERE State = 'Active'");
foreach (ManagementObject session in sessionSearcher.Get())
{
    Console.WriteLine($"会话ID: {session["SessionId"]}, 用户名: {session["UserName"]}, 客户端: {session["ClientName"]}");
}

这个方法适合需要监控所有会话的场景,能直观看到每个会话的关联信息。

总结选择

  • 如果要区分同一客户端的不同用户会话:优先用会话ID,它是每个会话的唯一标识;
  • 如果要区分不同用户:直接用SID或用户名即可;
  • 如果需要批量管理会话:用WMI查询会更便捷。

内容的提问来源于stack exchange,提问作者DGZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:41:38