0

like the title said, i want to create a method to search a windows user session id by the domainname\username.

I already finished to read the currently logged in users, but id do not know to determine their session id.

My goal is to kill the session of specific users.

  • Possible duplicate of [Log off a Windows user locally using c#](http://stackoverflow.com/questions/14466373/log-off-a-windows-user-locally-using-c-sharp) –  Sep 28 '16 at 15:02

2 Answers2

1

Based on the code from: How do you retrieve a list of logged-in/connected users in .NET?

Modified a bit, the following code will list the logged in users and their corresponding session ids.

class Program
{
    static void Main(string[] args)
    {
        var userLogins = new UserLogins();

        // this code gets the users from localhost -
        // can change this to a remote hostname on the network
        var users = UserLogins.GetUsers("localhost");

        foreach (var user in users)
        {
            Console.WriteLine("User: " + user);
        }

        Console.ReadKey();

    }

    public class UserLogins
    {

        [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(
            System.IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out System.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
        }

        public static IntPtr OpenServer(String Name)
        {
            IntPtr server = WTSOpenServer(Name);
            return server;
        }
        public static void CloseServer(IntPtr ServerHandle)
        {
            WTSCloseServer(ServerHandle);
        }
        public static IEnumerable<UserInfo> GetUsers(String ServerName)
        {
            IntPtr serverHandle = IntPtr.Zero;
            List<String> resultList = new List<string>();
            serverHandle = OpenServer(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));
                Int32 currentSession = (int)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);

                        yield return new UserInfo
                        {
                            Domain = Marshal.PtrToStringAnsi(domainPtr),
                            User = Marshal.PtrToStringAnsi(userPtr),
                            SessionID = si.SessionID
                        };

                        WTSFreeMemory(userPtr);
                        WTSFreeMemory(domainPtr);
                    }

                    WTSFreeMemory(SessionInfoPtr);
                }
            }
            finally
            {
                CloseServer(serverHandle);
            }
        }
    }
    public class UserInfo
    {
        public string Domain { get; set; }
        public string User { get; set; }

        public int SessionID { get; set; }

        public override string ToString()
        {
            return string.Format("{0}\\{1}: {2}", Domain, User, SessionID);
        }
    }
}
Community
  • 1
  • 1
David_001
  • 5,703
  • 4
  • 29
  • 55
  • I tried this code, but i ended up how to access the users session id. Is all the informations stored in "user" here: Console.WriteLine("User: " + user); So the "user" has also stored the session id?? –  Sep 29 '16 at 11:40
  • Ok i figured out myself. But now if i run my application on a server and connect via remote, its says no user is logged in. –  Sep 29 '16 at 12:17
0

create a commandline application. call the command "query session" and store the results in a list for example sessionList. than you can say:

var sessionList = Process.Start("cmd", "c:\>query session").ToList();
sessionList = sessionList.Where(x => x.Username == "Piet")
foreach( var item in sessionList)
{
 console.WriteLine(item.id)
}
 

maybe you need to finetune it a little bit but it will work

  • there is no method .toList() for Process.Start Can you please tell me how am i able to send the output to a list? –  Sep 29 '16 at 11:36
  • if i run the process cmd query session i do not have the table which contains the user informations in the output stream. if i run query session manually from the command promt i get the information about my user. –  Sep 29 '16 at 14:11