Как получить текущее имя пользователя из службы Windows в .NET?

У меня есть служба Windows, для которой требуется имя пользователя, зарегистрированное в настоящее время. Я попробовал System.Environment.UserName, идентификатор Windows и аутентификацию формы Windows, но все возвращают " Система", поскольку пользователь работает как служба в привилегированном режиме. Есть ли способ получить текущее имя пользователя без изменения моей учетной записи службы?

Ответ 1

Я использовал запрос WMI (см. также ответ Tapas). Все остальное возвращало имя пользователя службы.

Ответ 2

Это запрос WMI, чтобы получить имя пользователя:

ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem");
ManagementObjectCollection collection = searcher.Get();
string username = (string)collection.Cast<ManagementBaseObject>().First()["UserName"];

Вам нужно будет добавить System.Management в разделе Ссылки вручную.

Ответ 3

Если вы находитесь в сети пользователей, то имя пользователя будет другим:

Environment.UserName

Будет отображаться формат: "Имя пользователя", а не

System.Security.Principal.WindowsIdentity.GetCurrent().Name

Будет отображаться формат: "Имя сети\Имя пользователя"

Выберите нужный формат.

Ответ 4

Решение ManagementObjectSearcher ( "SELECT UserName FROM Win32_ComputerSystem" ) отлично работало для меня. НО это не работает, если служба запускается через подключение к удаленному рабочему столу. Чтобы обойти это, мы можем запросить имя пользователя для интерактивного процесса, который всегда выполняется на ПК: explorer.exe. Таким образом, мы всегда получаем текущее имя пользователя, зарегистрированное в Windows, из нашей службы Windows:

foreach (System.Management.ManagementObject Process in Processes.Get())
{
    if (Process["ExecutablePath"] != null && 
        System.IO.Path.GetFileName(Process["ExecutablePath"].ToString()).ToLower() == "explorer.exe" )
    {
        string[] OwnerInfo = new string[2];
        Process.InvokeMethod("GetOwner", (object[])OwnerInfo);

        Console.WriteLine(string.Format("Windows Logged-in Interactive UserName={0}", OwnerInfo[0]));

        break;
    }
}

Ответ 5

Измененный код Ответ на тапас:

Dim searcher As New ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem")
Dim collection As ManagementObjectCollection = searcher.[Get]()
Dim username As String
For Each oReturn As ManagementObject In collection
    username = oReturn("UserName")
Next

Ответ 6

Попробуйте WindowsIdentity.GetCurrent(). Вам нужно добавить ссылку на System.Security.Principal

Ответ 7

Вы также можете попробовать

System.Environment.GetEnvironmentVariable("UserName");

Ответ 8

На всякий случай, если кто-то ищет отображаемое имя пользователя, а не имя пользователя, как я.

Здесь угощение:

System.DirectoryServices.AccountManagement.UserPrincipal.Current.DisplayName.

Добавьте ссылку на System.DirectoryServices.AccountManagement в свой проект.

Ответ 9

Завершение ответа от @xanblax

private static string getUserName()
    {
        SelectQuery query = new SelectQuery(@"Select * from Win32_Process");
        using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
        {
            foreach (System.Management.ManagementObject Process in searcher.Get())
            {
                if (Process["ExecutablePath"] != null &&
                    string.Equals(Path.GetFileName(Process["ExecutablePath"].ToString()), "explorer.exe", StringComparison.OrdinalIgnoreCase))
                {
                    string[] OwnerInfo = new string[2];
                    Process.InvokeMethod("GetOwner", (object[])OwnerInfo);

                    return OwnerInfo[0];
                }
            }
        }
        return "";
    }