C#获取RDC / RDP和"控制台"会话信息 [英] C# Get RDC/RDP and "Console" Session information

查看:1013
本文介绍了C#获取RDC / RDP和"控制台"会话信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想找回一些RDC / RDP和控制台通过C#编程登录信息。



我想开发一个简单的控制台应用程序(.EXE)这样我可以retreive从任务管理器中的信息 - 我们的域(Windows Server 2003中的x86,或2008R2 x64)的任何远程计算机>用户选项卡。



这表明,如果一个人登录到服务器直接(即控制台)或通过RDC / RDP(包括是否仍然活跃的客户端)或断开,如果它是暂停(即他们没有注销而只是关闭了RDC / RDP窗口暂时)



我的所有服务器上管理员权限,可以配置任何窗口服务/启用需要的防火墙规则/禁用(如果需要)



我觉得我有可能会使用WMI(使用System.Management),但我已经从谷歌找到了例子只检索现有的用户。

  //方法1 
变种搜索=新ManagementObjectSearcher(
选择username的的Win32_ComputerSystem);
变种集合= Searcher.Get();
的foreach(在收集的ManagementObject项)
{
Console.WriteLine(入门[用户名]);
}

//方法2
字符串电脑=somecomputername;
变种搜索=新ManagementObjectSearcher(
电脑+ @root\CIMV2,SELECT * FROM Win32_TerminalService);
变种集合= Searcher.Get();
的foreach(在收集的ManagementObject项)
{
//写出来(虽然用户名心不是从示例中列出我发现)
}


解决方案

这会给你你需要的一切。只需拨打 ListSessions ,并通过在服务器名称。为了获得更多的会话信息,通过服务器名称的SessionID GetSessionInfo

 使用系统; 
使用System.Collections.Generic;
使用System.Text;使用System.Runtime.InteropServices
;

命名空间TerminalTools
{
公共类TermServicesManager
{

函数[DllImport(wtsapi32.dll)]
静EXTERN的IntPtr WTSOpenServer([的MarshalAs(UnmanagedType.LPStr)]字符串pServerName);

函数[DllImport(wtsapi32.dll)]
静态外部无效WTSCloseServer(IntPtr的hServer);

函数[DllImport(Wtsapi32.dll)]
公共静态外部布尔WTSQuerySessionInformation(IntPtr的hServer,诠释的sessionId,WTS_INFO_CLASS wtsInfoClass,
OUT System.IntPtr ppBuffer,出UINT pBytesReturned );

函数[DllImport(wtsapi32.dll)]
静态外部的Int32 WTSEnumerateSessions(IntPtr的hServer,[的MarshalAs(UnmanagedType.U4)的Int32保留,
[的MarshalAs(UnmanagedType。 U4)的Int32版本,楼盘的IntPtr ppSessionInfo,[的MarshalAs(UnmanagedType.U4)裁判的Int32 pCount);

函数[DllImport(wtsapi32.dll)]
静态外部无效WTSFreeMemory(IntPtr的pMemory);

[StructLayout(LayoutKind.Sequential)]
私人结构WTS_SESSION_INFO
{
公众的Int32的SessionID;
[的MarshalAs(UnmanagedType.LPStr)
公共字符串pWinStationName;
公共WTS_CONNECTSTATE_CLASS国家;
}

[StructLayout(LayoutKind.Sequential)]
公共结构WTS_CLIENT_ADDRESS
{
公共UINT AddressFamily;
[的MarshalAs(UnmanagedType.ByValArray,SizeConst = 20)]
公共字节[]地址;
}

[StructLayout(LayoutKind.Sequential)]
公共结构WTS_CLIENT_DISPLAY
{
公共UINT Horizo​​ntalResolution;
公共UINT VerticalResolution;
公共UINT颜色质量汇总;
}

公共枚举WTS_CONNECTSTATE_CLASS
{
激活,
连接,
ConnectQuery,
阴影,
断开,
空闲,
听着,
复位,
下,
初始化
}

公共枚举WTS_INFO_CLASS
{
InitialProgram = 0,
的ApplicationName = 1,
工作目录= 2,
OEMID = 3,
的SessionID = 4,
用户名= 5,
WinStationName = 6,
域名= 7,
ConnectState = 8,
ClientBuildNumber = 9,
CLIENTNAME = 10,
ClientDirectory = 11,
ClientProductId = 12,
ClientHardwareId = 13,
ClientAddress = 14,
ClientDisplay = 15,
ClientProtocolType = 16
}

私人静态的IntPtr OpenServer的(字符串名称)
{
IntPtr的服务器= WTSOpenServer(姓名);
返回服务器;
}

私有静态无效CloseServer(IntPtr的ServerHandle)
{
WTSCloseServer(ServerHandle);
}

公共静态列表< TerminalSessionData> ListSessions(字符串服务器名称)
{
IntPtr的服务器= IntPtr.Zero;
名单,LT; TerminalSessionData> RET =新的List< TerminalSessionData>();
服务器= OpenServer的(服务器);


{
IntPtr的ppSessionInfo = IntPtr.Zero;

的Int32计数= 0;
的Int32 RETVAL = WTSEnumerateSessions(服务器,0,1,参考ppSessionInfo,引用计数);
的Int32数据大小= Marshal.SizeOf(typeof运算(WTS_SESSION_INFO));

Int64的电流=(INT)ppSessionInfo;

如果(RETVAL!= 0)
{
的for(int i = 0; I<计数;我++)
{
WTS_SESSION_INFO SI = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)当前的typeof(WTS_SESSION_INFO));
电流+ =数据大小;

ret.Add(新TerminalSessionData(si.SessionID,si.State,si.pWinStationName));
}

WTSFreeMemory(ppSessionInfo);
}
}
终于
{
CloseServer(服务器);
}

返回RET;
}

公共静态TerminalSessionInfo GetSessionInfo(字符串服务器名称,诠释的SessionID)
{
IntPtr的服务器= IntPtr.Zero;
服务器= OpenServer的(服务器);
System.IntPtr缓冲= IntPtr.Zero;
UINT bytesReturned;
TerminalSessionInfo数据=新TerminalSessionInfo();


{
布尔工作= WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.ApplicationName,出缓冲器,出bytesReturned);

如果(工作!)
返回数据;

串strData是= Marshal.PtrToStringAnsi(缓冲);
data.ApplicationName = strData是;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.ClientAddress,出缓冲器,出bytesReturned);

如果(工作!)
返回数据;

WTS_CLIENT_ADDRESS SI =(WTS_CLIENT_ADDRESS)Marshal.PtrToStructure((System.IntPtr)缓冲的typeof(WTS_CLIENT_ADDRESS));
data.ClientAddress = SI;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.ClientBuildNumber,出缓冲器,出bytesReturned);

如果(工作!)
返回数据;

INT LDATA = Marshal.ReadInt32(缓冲);
data.ClientBuildNumber = LDATA;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.ClientDirectory,出缓冲器,出bytesReturned);

如果(工作!)
返回数据;

strData是= Marshal.PtrToStringAnsi(缓冲);
data.ClientDirectory = strData是;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.ClientDisplay,出缓冲器,出bytesReturned);

如果(工作!)
返回数据;

WTS_CLIENT_DISPLAY CD =(WTS_CLIENT_DISPLAY)Marshal.PtrToStructure((System.IntPtr)缓冲的typeof(WTS_CLIENT_DISPLAY));
data.ClientDisplay = CD;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.ClientHardwareId,出缓冲器,出bytesReturned);

如果(工作!)
返回数据;

LDATA = Marshal.ReadInt32(缓冲);
data.ClientHardwareId = LDATA;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.ClientName,出缓冲器,出bytesReturned);
strData是= Marshal.PtrToStringAnsi(缓冲);
data.ClientName = strData是;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.ClientProductId,出缓冲器,出bytesReturned);
的Int16 intData = Marshal.ReadInt16(缓冲);
data.ClientProductId = intData;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.ClientProtocolType,出缓冲器,出bytesReturned);
intData = Marshal.ReadInt16(缓冲液);
data.ClientProtocolType = intData;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.ConnectState,出缓冲器,出bytesReturned);
LDATA = Marshal.ReadInt32(缓冲液);
data.ConnectState =(WTS_CONNECTSTATE_CLASS)Enum.ToObject(typeof运算(WTS_CONNECTSTATE_CLASS),LDATA);

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.DomainName,出缓冲器,出bytesReturned);
strData是= Marshal.PtrToStringAnsi(缓冲);
data.DomainName = strData是;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.InitialProgram,出缓冲器,出bytesReturned);
strData是= Marshal.PtrToStringAnsi(缓冲);
data.InitialProgram = strData是;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.OEMId,出缓冲器,出bytesReturned);
strData是= Marshal.PtrToStringAnsi(缓冲);
data.OEMId = strData是;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.SessionId,出缓冲器,出bytesReturned);
LDATA = Marshal.ReadInt32(缓冲液);
data.SessionId = LDATA;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.UserName,出缓冲器,出bytesReturned);
strData是= Marshal.PtrToStringAnsi(缓冲);
data.UserName = strData是;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.WinStationName,出缓冲器,出bytesReturned);
strData是= Marshal.PtrToStringAnsi(缓冲);
data.WinStationName = strData是;

=工作WTSQuerySessionInformation(服务器的SessionID,
WTS_INFO_CLASS.WorkingDirectory,出缓冲器,出bytesReturned);
strData是= Marshal.PtrToStringAnsi(缓冲);
data.WorkingDirectory = strData是;
}
终于
{
WTSFreeMemory(缓冲);
缓冲= IntPtr.Zero;
CloseServer(服务器);
}

返回数据;
}

}

公共类TerminalSessionData
{
公众诠释的SessionID;
公共TermServicesManager.WTS_CONNECTSTATE_CLASS ConnectionState;
公共字符串工作站名称;

公共TerminalSessionData(INT的sessionId,TermServicesManager.WTS_CONNECTSTATE_CLASS connState,串工作站名称)
{
的SessionID =的sessionId;
ConnectionState = connState;
工作站名称=工作站名称;
}

公共重写字符串的ToString()
{
返回的String.Format({0} {1} {2}的SessionID,ConnectionState,工作站名称);
}
}

公共类TerminalSessionInfo
{
公共字符串InitialProgram;
公共字符串应用程序名称;
公共字符串工作目录;
公共字符串OEMID;
公众诠释的SessionID;
公共字符串用户名;
公共字符串WinStationName;
公共字符串域名;
公共TermServicesManager.WTS_CONNECTSTATE_CLASS ConnectState;
公众诠释ClientBuildNumber;
公共字符串CLIENTNAME;
公共字符串ClientDirectory;
公众诠释ClientProductId;
公众诠释ClientHardwareId;
公共TermServicesManager.WTS_CLIENT_ADDRESS ClientAddress;
公共TermServicesManager.WTS_CLIENT_DISPLAY ClientDisplay;
公众诠释ClientProtocolType;
}
}


I'm trying to retrieve some RDC/RDP and "Console" login information programmatically via C#.

I want to develop a simple console application (.EXE) such that I can retreive the information from Task Manager -> Users Tab of any remote computer on our domain (Windows Server 2003 x86, or 2008R2 x64).

This shows if a person is logged onto the server directly (i.e. the Console) or over RDC/RDP (including the client if it is still active) or disconnected if it is "suspended" (i.e. they have not logged off but just closed the RDC/RDP windows temporarily)

I have admin permissions on all servers and can configure any windows services/firewalls rules that need to be enabled/disabled (if required)

I think I have to probably use WMI (using System.Management) but the examples I have found from google only retrieve the existing user.

//Method 1
var searcher = new ManagementObjectSearcher(
               "SELECT UserName FROM Win32_ComputerSystem");
var collection = Searcher.Get();
foreach(ManagementObject entry in collection)
{
  Console.WriteLine(entry["UserName"]);
}

//Method 2
string computer = "somecomputername";   
var searcher = new ManagementObjectSearcher(
               computer + @"root\CIMV2", "SELECT * FROM Win32_TerminalService");
var collection = Searcher.Get();
foreach(ManagementObject entry in collection)
{
  //Write them out (although usernames isnt listed from the example I found)
}

解决方案

This will give you everything you need. Just call ListSessions and pass in the server name. To get additional session information, pass the ServerName and SessionId to GetSessionInfo.

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace TerminalTools
{
    public class TermServicesManager
    {

        [DllImport("wtsapi32.dll")]
        static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName);

        [DllImport("wtsapi32.dll")]
        static extern void WTSCloseServer(IntPtr hServer);

        [DllImport("Wtsapi32.dll")]
        public static extern bool WTSQuerySessionInformation(IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass,
            out System.IntPtr ppBuffer, out uint pBytesReturned);

        [DllImport("wtsapi32.dll")]
        static extern Int32 WTSEnumerateSessions(IntPtr hServer, [MarshalAs(UnmanagedType.U4)] Int32 Reserved,
            [MarshalAs(UnmanagedType.U4)] Int32 Version, ref IntPtr ppSessionInfo, [MarshalAs(UnmanagedType.U4)] ref Int32 pCount);

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

        [StructLayout(LayoutKind.Sequential)]
        private struct WTS_SESSION_INFO
        {
            public Int32 SessionID;
            [MarshalAs(UnmanagedType.LPStr)]
            public String pWinStationName;
            public WTS_CONNECTSTATE_CLASS State;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct WTS_CLIENT_ADDRESS
        {
            public uint AddressFamily;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
            public byte[] Address;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct WTS_CLIENT_DISPLAY
        {
            public uint HorizontalResolution;
            public uint VerticalResolution;
            public uint ColorDepth;
        }

        public enum WTS_CONNECTSTATE_CLASS
        {
            Active,
            Connected,
            ConnectQuery,
            Shadow,
            Disconnected,
            Idle,
            Listen,
            Reset,
            Down,
            Init
        }

        public enum WTS_INFO_CLASS
        {
            InitialProgram = 0,
            ApplicationName = 1,
            WorkingDirectory = 2,
            OEMId = 3,
            SessionId = 4,
            UserName = 5,
            WinStationName = 6,
            DomainName = 7,
            ConnectState = 8,
            ClientBuildNumber = 9,
            ClientName = 10,
            ClientDirectory = 11,
            ClientProductId = 12,
            ClientHardwareId = 13,
            ClientAddress = 14,
            ClientDisplay = 15,
            ClientProtocolType = 16
        }

                        private static IntPtr OpenServer(string Name)
    {
        IntPtr server = WTSOpenServer(Name);
        return server;
    }

                    private static void CloseServer(IntPtr ServerHandle)
    {
        WTSCloseServer(ServerHandle);
    }

        public static List<TerminalSessionData> ListSessions(string ServerName)
        {
            IntPtr server = IntPtr.Zero;
            List<TerminalSessionData> ret = new List<TerminalSessionData>();
            server = OpenServer(ServerName);

            try
            {
                IntPtr ppSessionInfo = IntPtr.Zero;

                Int32 count = 0;
                Int32 retval = WTSEnumerateSessions(server, 0, 1, ref ppSessionInfo, ref count);
                Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));

                Int64 current = (int)ppSessionInfo;

                if (retval != 0)
                {
                    for (int i = 0; i < count; i++)
                    {
                        WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO));
                        current += dataSize;

                        ret.Add(new TerminalSessionData(si.SessionID, si.State, si.pWinStationName));
                    }

                    WTSFreeMemory(ppSessionInfo);
                }
            }
            finally
            {
                CloseServer(server);
            }

            return ret;
        }

        public static TerminalSessionInfo GetSessionInfo(string ServerName, int SessionId)
        {
            IntPtr server = IntPtr.Zero;
            server = OpenServer(ServerName);
            System.IntPtr buffer = IntPtr.Zero;
            uint bytesReturned;
            TerminalSessionInfo data = new TerminalSessionInfo();

            try
            {
                bool worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.ApplicationName, out buffer, out bytesReturned);

                if (!worked)
                    return data;

                string strData = Marshal.PtrToStringAnsi(buffer);
                data.ApplicationName = strData;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.ClientAddress, out buffer, out bytesReturned);

                if (!worked)
                    return data;

                WTS_CLIENT_ADDRESS si = (WTS_CLIENT_ADDRESS)Marshal.PtrToStructure((System.IntPtr)buffer, typeof(WTS_CLIENT_ADDRESS));
                data.ClientAddress = si;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.ClientBuildNumber, out buffer, out bytesReturned);

                if (!worked)
                    return data;

                int lData = Marshal.ReadInt32(buffer);
                data.ClientBuildNumber = lData;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.ClientDirectory, out buffer, out bytesReturned);

                if (!worked)
                    return data;

                strData = Marshal.PtrToStringAnsi(buffer);
                data.ClientDirectory = strData;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.ClientDisplay, out buffer, out bytesReturned);

                if (!worked)
                    return data;

                WTS_CLIENT_DISPLAY cd = (WTS_CLIENT_DISPLAY)Marshal.PtrToStructure((System.IntPtr)buffer, typeof(WTS_CLIENT_DISPLAY));
                data.ClientDisplay = cd;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.ClientHardwareId, out buffer, out bytesReturned);

                if (!worked)
                    return data;

                lData = Marshal.ReadInt32(buffer);
                data.ClientHardwareId = lData;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.ClientName, out buffer, out bytesReturned);
                strData = Marshal.PtrToStringAnsi(buffer);
                data.ClientName = strData;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.ClientProductId, out buffer, out bytesReturned);
                Int16 intData = Marshal.ReadInt16(buffer);
                data.ClientProductId = intData;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.ClientProtocolType, out buffer, out bytesReturned);
                intData = Marshal.ReadInt16(buffer);
                data.ClientProtocolType = intData;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.ConnectState, out buffer, out bytesReturned);
                lData = Marshal.ReadInt32(buffer);
                data.ConnectState = (WTS_CONNECTSTATE_CLASS)Enum.ToObject(typeof(WTS_CONNECTSTATE_CLASS), lData);

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.DomainName, out buffer, out bytesReturned);
                strData = Marshal.PtrToStringAnsi(buffer);
                data.DomainName = strData;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.InitialProgram, out buffer, out bytesReturned);
                strData = Marshal.PtrToStringAnsi(buffer);
                data.InitialProgram = strData;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.OEMId, out buffer, out bytesReturned);
                strData = Marshal.PtrToStringAnsi(buffer);
                data.OEMId = strData;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.SessionId, out buffer, out bytesReturned);
                lData = Marshal.ReadInt32(buffer);
                data.SessionId = lData;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.UserName, out buffer, out bytesReturned);
                strData = Marshal.PtrToStringAnsi(buffer);
                data.UserName = strData;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.WinStationName, out buffer, out bytesReturned);
                strData = Marshal.PtrToStringAnsi(buffer);
                data.WinStationName = strData;

                worked = WTSQuerySessionInformation(server, SessionId,
                    WTS_INFO_CLASS.WorkingDirectory, out buffer, out bytesReturned);
                strData = Marshal.PtrToStringAnsi(buffer);
                data.WorkingDirectory = strData;
            }
            finally
            {
                WTSFreeMemory(buffer);
                buffer = IntPtr.Zero;
                CloseServer(server);
            }

            return data;
        }

    }

    public class TerminalSessionData
    {
        public int SessionId;
        public TermServicesManager.WTS_CONNECTSTATE_CLASS ConnectionState;
        public string StationName;

                            public TerminalSessionData(int sessionId, TermServicesManager.WTS_CONNECTSTATE_CLASS connState, string stationName)
    {
        SessionId = sessionId;
        ConnectionState = connState;
        StationName = stationName;
    }

                    public override string ToString()
    {
        return String.Format("{0} {1} {2}", SessionId, ConnectionState, StationName);
    }
    }

    public class TerminalSessionInfo
    {
        public string InitialProgram;
        public string ApplicationName;
        public string WorkingDirectory;
        public string OEMId;
        public int SessionId;
        public string UserName;
        public string WinStationName;
        public string DomainName;
        public TermServicesManager.WTS_CONNECTSTATE_CLASS ConnectState;
        public int ClientBuildNumber;
        public string ClientName;
        public string ClientDirectory;
        public int ClientProductId;
        public int ClientHardwareId;
        public TermServicesManager.WTS_CLIENT_ADDRESS ClientAddress;
        public TermServicesManager.WTS_CLIENT_DISPLAY ClientDisplay;
        public int ClientProtocolType;
    }
}

这篇关于C#获取RDC / RDP和&QUOT;控制台&QUOT;会话信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆