2008-11-18 47 views
15

Tôi đang cố gắng lấy danh sách các quy trình hiện đang được sở hữu bởi người dùng hiện tại (Environment.UserName). Thật không may, lớp Process không có bất kỳ cách nào để nhận UserName của người dùng sở hữu một quy trình.Làm thế nào để bạn có được UserName của chủ sở hữu của một quá trình?

Làm cách nào để bạn có được UserName của người dùng là chủ sở hữu của quy trình sử dụng lớp học Process để tôi có thể so sánh nó với Environment.UserName?

Nếu giải pháp của bạn yêu cầu pinvoke, vui lòng cung cấp ví dụ về mã.

Trả lời

10

Các bài viết CodeProject How To Get Process Owner ID and Current User SID bởi Warlib mô tả làm thế nào để làm điều này sử dụng cả hai WMI và sử dụng API Win32 qua PInvoke.

Mã WMI đơn giản hơn nhiều nhưng thực thi chậm hơn. Câu hỏi của bạn không cho biết câu hỏi nào phù hợp hơn cho kịch bản của bạn.

2

Bạn có thể xem bằng cách sử dụng System.Management (WMI). Với điều đó bạn có thể truy vấn cây Win32_Process.

2

đây là MS link nhãn "GetOwner Phương pháp Class Win32_Process"

16

Cảm ơn, câu trả lời của bạn đã đưa tôi đi đúng hướng. Đối với những người cần mẫu mã:

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

Bạn sẽ gặp khó khăn khi nhận tên người dùng mà không phải là quản trị viên trên máy tính.

Không có phương pháp nào với WMI, thông qua OpenProcess hoặc sử dụng WTSEnumerateProcesses sẽ cung cấp cho bạn tên người dùng trừ khi bạn là quản trị viên. Cố gắng để kích hoạt SeDebugPrivilege vv cũng không hoạt động. Tôi vẫn thấy mã hoạt động mà không phải là quản trị viên.

Nếu có ai biết làm thế nào để có được điều này KHÔNG làm quản trị viên trên máy đang chạy, hãy viết cách thực hiện, vì tôi chưa biết cách bật cấp truy cập đó cho người dùng dịch vụ.

+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

Đã kiểm tra điều đó. Vấn đề là nó nhận được tên người dùng cho một phiên. Và nếu tôi mở 2 cửa sổ CMD với 2 người dùng khác nhau, cả hai đều có cùng một ID phiên (2). Và cả hai giải quyết cho cùng một người dùng, đó là sai. Taskmanager hiển thị chúng một cách chính xác. – Wolf5

+0

Tôi đã được đi từ vấn đề này cho một chút, nhưng họ sẽ không có ProcID khác nhau? Không thể nhớ những gì nó trả về, nhưng chỉ suy nghĩ to ở đây. – TomO

2

Đạo cụ cho Andrew Moore cho câu trả lời của anh ấy, tôi chỉ định dạng nó vì nó không biên dịch trong 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

Bạn sẽ cần thêm tham chiếu vào System.Management.dll để làm việc này.

Đây là những gì tôi đã sử dụng. Nó hoạt động trong .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); 
    } 
} 
Các vấn đề liên quan