Предпочтительный способ получения имени клиента из сеанса сервера терминалов

Мне нужно получить базовое имя клиентского ПК из сеанса терминального сервера пользователя.

Я знаю, что он живет в HKEY_CURRENT_USER\Volatile Environment\CLIENTNAME, но есть ли другой (желательно родной .net) способ его получить?


person beakersoft    schedule 14.03.2011    source источник


Ответы (2)


Я не видел управляемого API для этого. Единственные способы получения этой информации на основе API, которые я мог видеть, — это WMI или собственный API служб терминалов в Windows.

Вот пример, который возвращает имя клиента с помощью 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);
    }
}
person Andrew Brown    schedule 16.03.2011
comment
Спасибо большое!!! Вы гений!!! И спасибо за такое подробное объяснение и добавление кода. - person Peppo; 19.11.2019
comment
давно, но знаете ли вы, почему WTS_INFO_CLASS.WTSUserName возвращает локального пользователя, а не пользователя удаленного сеанса? - person Mar Tin; 09.04.2020

Чтобы ответить на эти вопросы, на веб-сайте Citrix Developer Network размещен проект C#, который предоставляет код для список сеансов и их IP-адресов на RDP-сервере:

Как получить IP-адрес клиента и имя хоста клиента с помощью API служб терминалов

person Renaud Bompuis    schedule 18.10.2011