如何获得进程所有者的UserName?

时间:2008-11-18 22:51:55

标签: c# .net process

我正在尝试获取当前用户(Environment.UserName)当前拥有的进程列表。遗憾的是,Process类没有任何方法可以获取用户拥有进程的UserName。

如何使用Process类获取作为流程所有者的用户的UserName,以便将其与Environment.UserName进行比较?

如果您的解决方案需要pinvoke,请提供代码示例。

7 个答案:

答案 0 :(得分:16)

谢谢,你的回答让我走上了正确的道路。对于那些需要代码示例的人:

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();
    }
}

答案 1 :(得分:10)

How To Get Process Owner ID and Current User SID下的CodeProject文章Warlib描述了如何使用WMI和通过PInvoke使用Win32 API来实现此目的。

WMI代码更简单但执行速度更慢。您的问题并未表明哪种情况更适合您的方案。

答案 2 :(得分:2)

您可以查看使用System.Management(WMI)。有了它,您可以查询Win32_Process树。

答案 3 :(得分:2)

这里是MS link标记为“Win32_Process类的GetOwner方法”

答案 4 :(得分:2)

如果不是计算机管理员,您将很难获得用户名。

除非您是管理员,否则通过OpenProcess或使用WTSEnumerateProcesses的WMI方法都不会为您提供用户名。试图启用SeDebugPrivilege等也不起作用。我仍然需要看到一个无需管理员即可运行的代码。

如果有人知道怎么做这个没有成为正在运行的机器上的管理员,请写下如何做,因为我还没有找到如何启用对服务用户的访问级别。

答案 5 :(得分:2)

向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;
}

答案 6 :(得分:0)

您需要添加对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);
    }
}