Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

[c#] Как узнать имя текущего пользователя в Windows Service

18K
16 ноября 2011 года
imAlex
179 / / 29.07.2010
Всем привет.
Данный вопрос поднимался неоднократно в нете. Однако ни один из предложенных вариантов не дает нужного результата.
Итак, есть служба (она естественно запускается от имени SYSTEM). Мне необходимо узнать имя активного пользователя. В нете нашел один вариант подходящий под описание
Class:
Код:
class Machine
    {
        [DllImport("secur32.dll", CharSet=CharSet.Auto)]
        public static extern int GetUserNameEx (int nameFormat, StringBuilder userName, ref uint userNameSize);

        public enum NameFormat:int
        {
        NameUnknown = 0,
        NameFullyQualifiedDN = 1,
        NameSamCompatible = 2,
        NameDisplay = 3,
        NameUniqueId = 6,
        NameCanonical = 7,
        NameUserPrincipal = 8,
        NameCanonicalEx = 9,
        NameServicePrincipal = 10,
        NameDnsDomain = 12
        };
        #endregion
    }

вызываем:
 
Код:
size = 100;
                    Machine.GetUserNameEx((int)Machine.NameFormat.NameSamCompatible, builder, ref size);
                    username = builder.ToString();


однако в результате получаем не имя пользователя а полное имя компьютера.
Подскажите, как можно получить имя пользователя?
5
16 ноября 2011 года
hardcase
4.5K / / 09.08.2005
"Активных" пользователей может быть много. Подробнее тут (см. последние сообщения).
18K
16 ноября 2011 года
imAlex
179 / / 29.07.2010
Спасибо за ответ.
Я знаю, что Активных может быть много. Однако меня интересует лиш тот случай, когда может быть один активный пользователь (правило домена).
Сейчас почитаю по вашей ссылке.
18K
16 ноября 2011 года
imAlex
179 / / 29.07.2010
А можно поподробнее про данную связку?
То-есть мне необходимо получить ID текущей сессии и по нему узнать имя пользователя?
Если это так, то встает вопрос: Как узнать имя по ID?
5
16 ноября 2011 года
hardcase
4.5K / / 09.08.2005
Читайте документацию. WTS_INFO_CLASS
5
16 ноября 2011 года
hardcase
4.5K / / 09.08.2005
Простейший пример:
Код:
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

enum WTSInfoClass
{
    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
}

class Program
{
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern uint WTSGetActiveConsoleSessionId();

    [DllImport("Wtsapi32.dll", SetLastError = true)]
    static extern bool WTSQuerySessionInformation(
        IntPtr hServer,
        uint sessionId,
        WTSInfoClass wtsInfoClass,
        out IntPtr ppBuffer,
        out uint pBytesReturned);

    [DllImport("wtsapi32.dll", SetLastError = true)]
    static extern void WTSFreeMemory(IntPtr memory);

    unsafe static void Main(string[] args)
    {
        var sessionId = WTSGetActiveConsoleSessionId();
        IntPtr pUserName;
        uint bytesReturned;
        if (!WTSQuerySessionInformation(IntPtr.Zero, sessionId, WTSInfoClass.WTSUserName, out pUserName, out bytesReturned))
            throw new Win32Exception();
        Console.WriteLine(new string((sbyte*)pUserName.ToPointer()));
        WTSFreeMemory(pUserName);
    }
}
18K
16 ноября 2011 года
imAlex
179 / / 29.07.2010
Спасибо. Разобрался. Заработало.
Однако по приведенной вами ссылке написано сл.:
Цитата:
сама служба должна запускаться достаточно рано, иначе можно
прозевать самый первый логин. Решение — добавить службу в одну из подходящих групп загрузки.


Мне не совсем понятно что это и как настроить. Подскажете?

5
16 ноября 2011 года
hardcase
4.5K / / 09.08.2005
Цитата: imAlex
Спасибо. Разобрался. Заработало.
Однако по приведенной вами ссылке написано сл.:

Мне не совсем понятно что это и как настроить. Подскажете?


Для использования WTS* функций (за исключением WTSGetActiveConsoleSessionId) вашу службу стоит сделать зависимой от TermService. Это можно сделать установив свойство ServicesDependedOn инсталлятора сервиса.

18K
18 ноября 2011 года
imAlex
179 / / 29.07.2010
Спасибо. Получилось.
У меня есть еще такой вопрос: А можно ли получать сообщение от системы о включении СкринСэйвера? То-есть я знаю так проверить на активность в данный момент, но больно уж не хочется запускать цикл с постоянной проверкой.
5
18 ноября 2011 года
hardcase
4.5K / / 09.08.2005
Я в этом не спец, но судя по всему тут два варианта: периодически (по таймеру) вызывать SystemParametersInfo, либо перехватывать запуск процесса скринсейвера. Имя процесса можно посмотреть тут: HKEY_USERS\{SID_Юзера}\Control Panel\Desktop\SCRNSAVE.EXE. Если этого значения нет - значит скринсейвер не настроен.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог