C#获取RDC / RDP和"控制台"会话信息 [英] C# Get RDC/RDP and "Console" Session information
问题描述
我想找回一些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 $ C $ 。C>
使用系统;
使用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 HorizontalResolution;
公共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和"控制台"会话信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!