2008-11-18 9 views
15

Estoy tratando de obtener una lista de procesos actualmente propiedad del usuario actual (Environment.UserName). Desafortunadamente, la clase Process no tiene ninguna forma de obtener el nombre de usuario del usuario que posee un proceso.¿Cómo se obtiene el nombre de usuario del propietario de un proceso?

¿Cómo se obtiene el nombre de usuario del usuario que es el propietario de un proceso utilizando la clase Process para que pueda compararlo con Environment.UserName?

Si su solución requiere un pinvoke, proporcione un ejemplo de código.

Respuesta

10

El artículo CodeProject How To Get Process Owner ID and Current User SID por Warlib describe cómo hacer esto utilizando tanto WMI y el uso de la API de Win32 a través de PInvoke.

El código WMI es mucho más simple pero más lento de ejecutar. Su pregunta no indica cuál sería más apropiada para su situación.

2

Puede utilizar System.Management (WMI). Con eso puedes consultar el árbol Win32_Process.

2

aquí es el MS link etiquetado como "Método GetOwner de la Clase Win32_Process"

16

Gracias, sus respuestas me pusieron en el camino correcto. Para aquellos que necesitan un ejemplo de código:

public class App 
{ 
    public static void Main(string[] Args) 
    { 
     Management.ManagementObjectSearcher Processes = new Management.ManagementObjectSearcher("SELECT * FROM Win32_Process"); 

     foreach (Management.ManagementObject Process in Processes.Get()) { 
      if (Process["ExecutablePath"] != null) { 
       string ExecutablePath = Process["ExecutablePath"].ToString(); 

       string[] OwnerInfo = new string[2]; 
       Process.InvokeMethod("GetOwner", (object[]) OwnerInfo); 

       Console.WriteLine(string.Format("{0}: {1}", IO.Path.GetFileName(ExecutablePath), OwnerInfo[0])); 
      } 
     } 

     Console.ReadLine(); 
    } 
} 
2

Tendrán dificultades para obtener el nombre de usuario sin ser un administrador en la computadora.

Ninguno de los métodos con WMI, a través de OpenProcess o utilizando el WTSEnumerateProcesses le dará el nombre de usuario a menos que sea un administrador. Intentar habilitar SeDebugPrivilege, etc., tampoco funciona. Todavía tengo que ver un código que funciona sin ser el administrador.

Si alguien sabe cómo hacerlo SIN ser un administrador en la máquina que se está ejecutando, por favor escriba cómo hacerlo, ya que no he descubierto cómo habilitar ese nivel de acceso a un usuario del servicio.

+0

https://social.msdn.microsoft.com/Forums/vstudio/en-US/aeff7e41-a4ba-4bf0-8677-81162040984d/retrieving-username-of-a -running-process? forum = netfxbcl – TomO

+0

Marcado ese. El problema es que obtiene el nombre de usuario para una sesión. Y si abro 2 ventanas de CMD con 2 usuarios diferentes, ambos tienen la misma ID de sesión (2). Y ambos resuelven al mismo usuario, lo cual es incorrecto. Taskmanager los muestra correctamente. – Wolf5

+0

He estado alejado de este problema por un tiempo, pero ¿no tendrían diferentes ProcID? No recuerdo lo que devuelve, pero solo pienso en voz alta aquí. – TomO

2

Apoyos a Andrew Moore por su respuesta, simplemente estoy formateándolo porque no compiló en C# 3.5.

private string GetUserName(string procName) 
{ 
    string query = "SELECT * FROM Win32_Process WHERE Name = \'" + procName + "\'"; 
    var procs = new System.Management.ManagementObjectSearcher(query); 
    foreach (System.Management.ManagementObject p in procs.Get()) 
    { 
     var path = p["ExecutablePath"]; 
     if (path != null) 
     { 
      string executablePath = path.ToString(); 
      string[] ownerInfo = new string[2]; 
      p.InvokeMethod("GetOwner", (object[])ownerInfo); 
      return ownerInfo[0]; 
     } 
    } 
    return null; 
} 
0

Usted tendrá que añadir una referencia a System.Management.dll para que esto funcione.

Esto es lo que terminé usando. Funciona en .NET 3.5:

using System.Linq; 
using System.Management; 

class Program 
{ 
    /// <summary> 
    /// Adapted from https://www.codeproject.com/Articles/14828/How-To-Get-Process-Owner-ID-and-Current-User-SID 
    /// </summary> 
    public static void GetProcessOwnerByProcessId(int processId, out string user, out string domain) 
    { 
     user = "???"; 
     domain = "???"; 

     var sq = new ObjectQuery("Select * from Win32_Process Where ProcessID = '" + processId + "'"); 
     var searcher = new ManagementObjectSearcher(sq); 
     if (searcher.Get().Count != 1) 
     { 
      return; 
     } 
     var process = searcher.Get().Cast<ManagementObject>().First(); 
     var ownerInfo = new string[2]; 
     process.InvokeMethod("GetOwner", ownerInfo); 

     if (user != null) 
     { 
      user = ownerInfo[0]; 
     } 
     if (domain != null) 
     { 
      domain = ownerInfo[1]; 
     } 
    } 

    public static void Main() 
    { 
     var processId = System.Diagnostics.Process.GetCurrentProcess().Id; 
     string user; 
     string domain; 
     GetProcessOwnerByProcessId(processId, out user, out domain); 
     System.Console.WriteLine(domain + "\\" + user); 
    } 
} 
Cuestiones relacionadas