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
}
[c#] Как узнать имя текущего пользователя в Windows Service
Данный вопрос поднимался неоднократно в нете. Однако ни один из предложенных вариантов не дает нужного результата.
Итак, есть служба (она естественно запускается от имени SYSTEM). Мне необходимо узнать имя активного пользователя. В нете нашел один вариант подходящий под описание
Class:
Код:
вызываем:
Код:
size = 100;
Machine.GetUserNameEx((int)Machine.NameFormat.NameSamCompatible, builder, ref size);
username = builder.ToString();
Machine.GetUserNameEx((int)Machine.NameFormat.NameSamCompatible, builder, ref size);
username = builder.ToString();
однако в результате получаем не имя пользователя а полное имя компьютера.
Подскажите, как можно получить имя пользователя?
тут (см. последние сообщения).
"Активных" пользователей может быть много. Подробнее
Я знаю, что Активных может быть много. Однако меня интересует лиш тот случай, когда может быть один активный пользователь (правило домена).
Сейчас почитаю по вашей ссылке.
То-есть мне необходимо получить ID текущей сессии и по нему узнать имя пользователя?
Если это так, то встает вопрос: Как узнать имя по ID?
Читайте документацию.
Код:
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);
}
}
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);
}
}
Однако по приведенной вами ссылке написано сл.:
Цитата:
сама служба должна запускаться достаточно рано, иначе можно
прозевать самый первый логин. Решение — добавить службу в одну из подходящих групп загрузки.
прозевать самый первый логин. Решение — добавить службу в одну из подходящих групп загрузки.
Мне не совсем понятно что это и как настроить. Подскажете?
Цитата: imAlex
Спасибо. Разобрался. Заработало.
Однако по приведенной вами ссылке написано сл.:
Мне не совсем понятно что это и как настроить. Подскажете?
Однако по приведенной вами ссылке написано сл.:
Мне не совсем понятно что это и как настроить. Подскажете?
Для использования WTS* функций (за исключением WTSGetActiveConsoleSessionId) вашу службу стоит сделать зависимой от TermService. Это можно сделать установив свойство ServicesDependedOn инсталлятора сервиса.
У меня есть еще такой вопрос: А можно ли получать сообщение от системы о включении СкринСэйвера? То-есть я знаю так проверить на активность в данный момент, но больно уж не хочется запускать цикл с постоянной проверкой.
SystemParametersInfo, либо перехватывать запуск процесса скринсейвера. Имя процесса можно посмотреть тут: HKEY_USERS\{SID_Юзера}\Control Panel\Desktop\SCRNSAVE.EXE. Если этого значения нет - значит скринсейвер не настроен.
Я в этом не спец, но судя по всему тут два варианта: периодически (по таймеру) вызывать