Как получить текущее имя пользователя из службы Windows в .NET? - PullRequest
58 голосов
/ 07 марта 2011

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

Ответы [ 8 ]

77 голосов
/ 25 августа 2011

Это запрос WMI для получения имени пользователя:

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

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

34 голосов
/ 21 октября 2013

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

Environment.UserName

Формат отображения: «Имя пользователя», а не

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

Будет отображаться формат: 'NetworkName \ Username'

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

18 голосов
/ 12 июня 2013

ManagementObjectSearcher («ВЫБЕРИТЕ имя пользователя из 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;
    }
}
6 голосов
/ 22 сентября 2011

Модифицированный код Ответ Тапаса :

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
2 голосов
/ 07 марта 2011

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

1 голос
/ 09 февраля 2018

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

Вот удовольствие:

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

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

1 голос
/ 24 марта 2013

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

System.Environment.GetEnvironmentVariable("UserName");
0 голосов
/ 27 апреля 2019

Завершение ответа от @ 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 "";
    }
...