【发布时间】:2010-09-22 23:04:58
【问题描述】:
我正在尝试获取当前用户 (Environment.UserName) 当前拥有的进程列表。不幸的是,Process 类无法获取拥有进程的用户的 UserName。
如何使用Process 类获取作为进程所有者的用户的用户名,以便我可以将其与Environment.UserName 进行比较?
如果您的解决方案需要pinvoke,请提供代码示例。
【问题讨论】:
我正在尝试获取当前用户 (Environment.UserName) 当前拥有的进程列表。不幸的是,Process 类无法获取拥有进程的用户的 UserName。
如何使用Process 类获取作为进程所有者的用户的用户名,以便我可以将其与Environment.UserName 进行比较?
如果您的解决方案需要pinvoke,请提供代码示例。
【问题讨论】:
您需要添加对 System.Management.dll 的引用才能使其正常工作。
这是我最终使用的。它适用于 .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);
}
}
【讨论】:
谢谢,您的回答让我走上了正确的道路。对于那些需要代码示例的人:
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();
}
}
【讨论】:
向 Andrew Moore 提供答案,我只是格式化它,因为它没有在 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;
}
【讨论】:
如果不是计算机管理员,您将很难获得用户名。
除非您是管理员,否则使用 WMI、通过 OpenProcess 或使用 WTSEnumerateProcesses 的任何方法都不会为您提供用户名。尝试启用 SeDebugPrivilege 等也不起作用。我仍然需要查看无需管理员身份即可运行的代码。
如果有人知道如何在不成为正在运行的机器上的管理员的情况下获得此功能,请写下如何操作,因为我还没有找到如何为服务用户启用该级别的访问权限。
【讨论】:
Warlib 的 CodeProject 文章 How To Get Process Owner ID and Current User SID 描述了如何同时使用 WMI 和通过 PInvoke 使用 Win32 API 来执行此操作。
WMI 代码更简单,但执行速度较慢。您的问题并未表明哪个更适合您的方案。
【讨论】:
这里是MS link 标记为“Win32_Process 类的GetOwner 方法”
【讨论】:
您可能会考虑使用 System.Management (WMI)。这样你就可以查询 Win32_Process 树了。
【讨论】: