web-dev-qa-db-fra.com

Comment puis-je obtenir le nom d'utilisateur actuellement connecté à partir d'un service Windows dans .NET?

J'ai un service Windows qui nécessite le nom d'utilisateur actuellement enregistré. J'ai essayé System.Environment.UserName, Identité Windows et authentification Windows, mais tous renvoient "System" en tant qu’utilisateur car mon service s’exécute avec des privilèges système. Est-il possible d’obtenir le nom d’utilisateur actuellement connecté sans changer le type de compte de service?

58
Rajkishor Sahu

Ceci est une requête WMI pour obtenir le nom d'utilisateur:

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

Vous devrez ajouter System.Management sous Références manuellement.

78
Tapas

Si vous êtes dans un réseau d'utilisateurs, le nom d'utilisateur sera différent:

Environment.UserName

Format d'affichage: 'Nom d'utilisateur', plutôt que

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

Est-ce que le format d'affichage est 'NetworkName\Username'?

Choisissez le format que vous voulez.

34
Israel Margulies

La solution ManagementObjectSearcher ("SELECT UserName FROM Win32_ComputerSystem") a bien fonctionné pour moi. MAIS cela ne fonctionne pas si le service est démarré via une connexion Bureau à distance. Pour contourner ce problème, nous pouvons demander le nom d'utilisateur du propriétaire d'un processus interactif toujours exécuté sur un PC: Explorer.exe. De cette manière, nous obtenons toujours le nom d'utilisateur Windows actuellement connecté de notre service 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;
    }
}
19
xanblax

Code modifié de réponse de Tapas :

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
Vishal Bedre

Essayez WindowsIdentity.GetCurrent(). Vous devez ajouter une référence à System.Security.Principal

Juste au cas où quelqu'un cherche un utilisateur Nom d'affichage par opposition à Nom d'utilisateur , comme moi.

Voici le régal:

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

Ajouter une référence à System.DirectoryServices.AccountManagement dans votre projet.

1
Bhramar

Vous pouvez aussi essayer

System.Environment.GetEnvironmentVariable("UserName");
1
Adith

Compléter la réponse de @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 "";
    }
0
EAquino