Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you retrieve a list of logged-in/connected users in .NET?

Here's the scenario:

You have a Windows server that users remotely connect to via RDP. You want your program (which runs as a service) to know who is currently connected. This may or may not include an interactive console session.

Please note that this is the not the same as just retrieving the current interactive user.

I'm guessing that there is some sort of API access to Terminal Services to get this info?

like image 249
James Avatar asked Sep 25 '08 11:09

James


People also ask

How do I get a list of users logged onto a server?

Step 1- Open the Command Line Interface by running "cmd" in the run dialog box (Win + R). Step 2- Type query user and press Enter. It will list all users that are currently logged on your computer.

How can I tell who is logged into Windows?

Press the Windows logo key + R simultaneously to open the Run box. Type cmd and press Enter. When the Command Prompt window opens, type query user and press Enter. It will list all users that are currently logged on your computer.

How do I see who is logged into a Windows 2012 Server?

Log in to Windows Server 2012 R2 and follow the instructions below to view the active remote users: Right click the taskbar and select Task Manager from the menu. Switch to the Users tab. Right click one of the existing columns, such as User or Status, and then select Session from the context menu.


1 Answers

Here's my take on the issue:

using System; using System.Collections.Generic; using System.Runtime.InteropServices;  namespace EnumerateRDUsers {   class Program   {     [DllImport("wtsapi32.dll")]     static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] string pServerName);      [DllImport("wtsapi32.dll")]     static extern void WTSCloseServer(IntPtr hServer);      [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);      [DllImport("wtsapi32.dll")]     static extern bool WTSQuerySessionInformation(         IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out IntPtr ppBuffer, out uint pBytesReturned);      [StructLayout(LayoutKind.Sequential)]     private struct WTS_SESSION_INFO     {       public Int32 SessionID;        [MarshalAs(UnmanagedType.LPStr)]       public string pWinStationName;        public WTS_CONNECTSTATE_CLASS State;     }      public enum WTS_INFO_CLASS     {       WTSInitialProgram,       WTSApplicationName,       WTSWorkingDirectory,       WTSOEMId,       WTSSessionId,       WTSUserName,       WTSWinStationName,       WTSDomainName,       WTSConnectState,       WTSClientBuildNumber,       WTSClientName,       WTSClientDirectory,       WTSClientProductId,       WTSClientHardwareId,       WTSClientAddress,       WTSClientDisplay,       WTSClientProtocolType     }      public enum WTS_CONNECTSTATE_CLASS     {       WTSActive,       WTSConnected,       WTSConnectQuery,       WTSShadow,       WTSDisconnected,       WTSIdle,       WTSListen,       WTSReset,       WTSDown,       WTSInit     }      static void Main(string[] args)     {       ListUsers(Environment.MachineName);     }      public static void ListUsers(string serverName)     {       IntPtr serverHandle = IntPtr.Zero;       List<string> resultList = new List<string>();       serverHandle = WTSOpenServer(serverName);        try       {         IntPtr sessionInfoPtr = IntPtr.Zero;         IntPtr userPtr = IntPtr.Zero;         IntPtr domainPtr = IntPtr.Zero;         Int32 sessionCount = 0;         Int32 retVal = WTSEnumerateSessions(serverHandle, 0, 1, ref sessionInfoPtr, ref sessionCount);         Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));         IntPtr currentSession = sessionInfoPtr;         uint bytes = 0;          if (retVal != 0)         {           for (int i = 0; i < sessionCount; i++)           {             WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)currentSession, typeof(WTS_SESSION_INFO));             currentSession += dataSize;              WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSUserName, out userPtr, out bytes);             WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSDomainName, out domainPtr, out bytes);              Console.WriteLine("Domain and User: " + Marshal.PtrToStringAnsi(domainPtr) + "\\" + Marshal.PtrToStringAnsi(userPtr));              WTSFreeMemory(userPtr);              WTSFreeMemory(domainPtr);           }            WTSFreeMemory(sessionInfoPtr);         }       }       finally       {         WTSCloseServer(serverHandle);       }      }    } } 
like image 161
Magnus Johansson Avatar answered Sep 29 '22 22:09

Magnus Johansson