2008-11-18 17 views
15

Próbuję uzyskać listę procesów aktualnie posiadanych przez bieżącego użytkownika (Environment.UserName). Niestety, klasa Process nie ma żadnego sposobu na uzyskanie UserName użytkownika będącego właścicielem procesu.Jak uzyskać nazwę użytkownika właściciela procesu?

Jak uzyskać UserName użytkownika, który jest właścicielem procesu korzystającego z klasy Process, aby można go było porównać z Environment.UserName?

Jeśli Twoje rozwiązanie wymaga pinvoke, podaj przykład kodu.

Odpowiedz

10

Wyrób CodeProject How To Get Process Owner ID and Current User SID przez Warlib opisuje jak to zrobić przy użyciu zarówno WMI i używając API Win32 poprzez PInvoke.

Kod WMI jest znacznie prostszy, ale jest wolniejszy do wykonania. Twoje pytanie nie wskazuje, które byłoby bardziej odpowiednie dla Twojego scenariusza.

2

Może zajrzeć do korzystania z System.Management (WMI). Dzięki temu możesz wysłać zapytanie do drzewa Win32_Process.

2

tutaj jest MS link oznaczony „GetOwner Metoda klasy Win32_Process”

16

Dzięki, twoje odpowiedzi stawiają mnie na właściwej ścieżce. Dla potrzebujących kodu:

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

Trudno będzie uzyskać nazwę użytkownika, nie będąc administratorem komputera.

Żadna z metod z WMI, poprzez OpenProcess lub przy użyciu WTSEnumerateProcesses nie poda nazwy użytkownika, chyba że jesteś administratorem. Próba włączenia SeDebugPrivilege itp. Również nie działa. Nadal muszę zobaczyć kod, który działa bez bycia administratorem.

Jeśli ktoś wie, jak to zrobić BEZ bycia adminem na komputerze, jest uruchamiany, proszę napisać, jak to zrobić, ponieważ nie dowiedziałem się, jak włączyć ten poziom dostępu do użytkownika usługi.

+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

Sprawdzone. Problem polega na tym, że otrzymuje nazwę użytkownika dla sesji. A jeśli otworzę 2 okna CMD z 2 różnymi użytkownikami, oba będą miały ten sam identyfikator sesji (2). I oba dotyczą tego samego użytkownika, który jest zły. Menedżer zadań wyświetla je poprawnie. – Wolf5

+0

Nie byłem zbytnio od tego problemu, ale czy nie mieliby oni innych ProcIDów? Nie pamiętam, co powraca, ale po prostu głośno tu myślę. – TomO

2

Rekwizyty dla Andrew Moore'a za odpowiedź, po prostu formatuję go, ponieważ nie skompilował się w 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

Musisz dodać odwołanie do System.Management.dll to zadziałało.

Oto, czego użyłem w końcu. To działa w .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); 
    } 
} 
Powiązane problemy