Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preferred way Of getting Client name From Terminal Server Session

I need to get the underlying client PC name from a user's terminal server session.

I know it lives in HKEY_CURRENT_USER\Volatile Environment\CLIENTNAME but is there another (preferably native .net) method of getting it?

like image 929
beakersoft Avatar asked Dec 05 '22 23:12

beakersoft


1 Answers

I didn't see a managed API for this. The only API-based ways I could see for getting at this information would be through WMI or the native Terminal Services API in Windows.

Here is an example that returns the client name using the WTSQuerySessionInformation API:

namespace com.stackoverflow
{
    using System;
    using System.Runtime.InteropServices;

    public class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(GetTerminalServicesClientName());
        }

        /// <summary>
        /// Gets the name of the client system.
        /// </summary>
        internal static string GetTerminalServicesClientName()
        {
            IntPtr buffer = IntPtr.Zero;

            string clientName = null;
            int bytesReturned;

            bool success = NativeMethods.WTSQuerySessionInformation(
                NativeMethods.WTS_CURRENT_SERVER_HANDLE,
                NativeMethods.WTS_CURRENT_SESSION,
                NativeMethods.WTS_INFO_CLASS.WTSClientName,
                out buffer,
                out bytesReturned);

            if (success)
            {
                clientName = Marshal.PtrToStringUni(
                    buffer,
                    bytesReturned / 2 /* Because the DllImport uses CharSet.Unicode */
                    );
                NativeMethods.WTSFreeMemory(buffer);
            }

            return clientName;
        }
    }

    public static class NativeMethods
    {
        public static readonly IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
        public const int WTS_CURRENT_SESSION = -1;

        public enum WTS_INFO_CLASS
        {
            WTSClientName = 10
        }

        [DllImport("Wtsapi32.dll", CharSet = CharSet.Unicode)]
        public static extern bool WTSQuerySessionInformation(
            IntPtr hServer,
            Int32 sessionId,
            WTS_INFO_CLASS wtsInfoClass,
            out IntPtr ppBuffer,
            out Int32 pBytesReturned);

        /// <summary>
        /// The WTSFreeMemory function frees memory allocated by a Terminal
        /// Services function.
        /// </summary>
        /// <param name="memory">Pointer to the memory to free.</param>
        [DllImport("wtsapi32.dll", ExactSpelling = true, SetLastError = false)]
        public static extern void WTSFreeMemory(IntPtr memory);
    }
}
like image 200
Andrew Brown Avatar answered May 16 '23 10:05

Andrew Brown