c# - visual - ¿Cómo se obtiene el nombre de usuario del propietario de un proceso?
system.diagnostics.process c# example (7)
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 UserName del usuario que posee un proceso.
¿Cómo se obtiene el nombre de usuario del usuario que es el propietario de un proceso que utiliza la clase Process
para que pueda compararlo con Environment.UserName
?
Si su solución requiere un pinvoke
, proporcione un ejemplo de código.
El artículo de CodeProject Cómo obtener el ID del propietario del proceso y el SID del usuario actual de Warlib describe cómo hacerlo utilizando tanto WMI como utilizando 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.
Puede ver usando System.Management (WMI). Con eso puedes consultar el árbol Win32_Process.
aquí está el enlace MS etiquetado como "Método GetOwner de la clase Win32_Process"
Te será difícil 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 el uso de 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 obtener esto 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.
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;
}
Gracias, tus respuestas me pusieron en el camino correcto. Para aquellos que necesitan una muestra 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();
}
}
Deberá agregar 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);
}
}