Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Retrieve Terminal Server session information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication19
{
class Program
{
static void Main(string[] args)
{
var WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
IntPtr ppSessionInfo;
uint pCount;
if (!WTSEnumerateSessions(
WTS_CURRENT_SERVER_HANDLE,
0,
1,
out ppSessionInfo,
out pCount))
{
return;
}
Console.WriteLine("===Enumerate Sessions===");
var iDataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
var current = new IntPtr(ppSessionInfo.ToInt32());
for (var i = 0; i < pCount; i++)
{
var sessionInfo = (WTS_SESSION_INFO)Marshal.PtrToStructure(current, typeof(WTS_SESSION_INFO));
//shift pointer value by the size of struct because of array
current = current + iDataSize;
Console.WriteLine("Session ID : " + sessionInfo.SessionID);
Console.WriteLine("Session State : " + sessionInfo.State);
Console.WriteLine("Workstation Name : " + sessionInfo.WinStationName);
var sessionId = sessionInfo.SessionID;
DumpSessionInfo(sessionId);
}
WTSFreeMemory(ppSessionInfo);
Console.WriteLine("===Dump Current Session===");
DumpSessionInfo();
Console.ReadLine();
}
static void DumpSessionInfo(uint sessionId = uint.MaxValue)
{
var WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
IntPtr ppBuffer;
uint iReturned;
if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,
sessionId,
WTS_INFO_CLASS.WTSClientAddress,
out ppBuffer,
out iReturned))
{
var clientAddres = (WTS_CLIENT_ADDRESS)Marshal.PtrToStructure(ppBuffer, typeof(WTS_CLIENT_ADDRESS));
if (clientAddres.AddressFamily == AddressFamilyType.AF_INET)
{
Console.WriteLine("IPv4Address:" + string.Join(".", clientAddres.Address.Skip(2).Take(4)));
}
}
if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,
sessionId,
WTS_INFO_CLASS.WTSClientName,
out ppBuffer,
out iReturned))
{
Console.WriteLine("ClientName: " + Marshal.PtrToStringAnsi(ppBuffer));
}
WTSFreeMemory(ppBuffer);
}
[DllImport("wtsapi32.dll")]
public static extern bool WTSEnumerateSessions(
IntPtr hServer,
uint reserved,
uint version,
out IntPtr ppSessionInfo,
out uint pCount);
[DllImport("wtsapi32.dll")]
public static extern bool WTSQuerySessionInformation(
IntPtr hServer,
uint sessionId,
WTS_INFO_CLASS wtsInfoClass,
out IntPtr ppBuffer,
out uint iBytesReturned);
[DllImport("wtsapi32.dll")]
static extern void WTSFreeMemory(IntPtr pMemory);
[StructLayout(LayoutKind.Sequential)]
private struct WTS_CLIENT_ADDRESS
{
public AddressFamilyType AddressFamily;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] Address;
}
public enum AddressFamilyType
{
AF_INET,
AF_INET6,
AF_IPX,
AF_NETBIOS,
AF_UNSPEC
}
[StructLayout(LayoutKind.Sequential)]
private struct WTS_SESSION_INFO
{
public uint SessionID;
[MarshalAs(UnmanagedType.LPStr)]
public string WinStationName;
public WTS_CONNECTSTATE_CLASS State;
}
public enum WTS_CONNECTSTATE_CLASS
{
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit
}
public enum WTS_INFO_CLASS
{
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType,
WTSIdleTime,
WTSLogonTime,
WTSIncomingBytes,
WTSOutgoingBytes,
WTSIncomingFrames,
WTSOutgoingFrames,
WTSClientInfo,
WTSSessionInfo,
WTSConfigInfo,
WTSValidationInfo,
WTSSessionAddressV4,
WTSIsRemoteSession
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.