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?
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.
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.
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;
}
}
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
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.
Vous pouvez aussi essayer
System.Environment.GetEnvironmentVariable("UserName");
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 "";
}