C# 如何获取进程所有者的用户名?

C# 如何获取进程所有者的用户名?,c#,.net,process,C#,.net,Process,我正在尝试获取当前用户Environment.UserName当前拥有的进程列表。不幸的是,Process类无法获取拥有进程的用户的用户名 如何获取用户的用户名,该用户是使用process类的流程的所有者,以便我可以将其与Environment.UserName进行比较 如果您的解决方案需要pinvoke,请提供一个代码示例。您可以考虑使用System.Management WMI。有了它,您可以查询Win32_进程树。这是Win32_进程类的标签GetOwner方法。的CodeProject文

我正在尝试获取当前用户Environment.UserName当前拥有的进程列表。不幸的是,Process类无法获取拥有进程的用户的用户名

如何获取用户的用户名,该用户是使用process类的流程的所有者,以便我可以将其与Environment.UserName进行比较


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

您可以考虑使用System.Management WMI。有了它,您可以查询Win32_进程树。

这是Win32_进程类的标签GetOwner方法。

的CodeProject文章介绍了如何使用WMI和通过PInvoke使用Win32 API来实现这一点


WMI代码简单得多,但执行速度较慢。您的问题并没有表明哪个更适合您的场景

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

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

如果您不是计算机管理员,则很难获取用户名

使用WMI、通过OpenProcess或使用WTSEnumerateProcess的任何方法都不会为您提供用户名,除非您是管理员。尝试启用SeDebugPrivilege等也不起作用。我仍然要看到一个代码,没有工作的管理员


如果有人知道如何在不担任运行机器管理员的情况下获取此信息,请写下如何实现,因为我还没有找到如何启用服务用户的访问级别。

请安德鲁·摩尔回答,我只是格式化它,因为它没有在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;
}
您需要添加对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);
    }
}

检查了那个。问题是它获取会话的用户名。如果我用两个不同的用户打开两个CMD窗口,它们都有相同的会话ID 2。两者都解析为同一个用户,这是错误的。Taskmanager正确地显示了它们。我已经远离这个问题一段时间了,但是它们不会有不同的ProcID吗?我记不起它返回了什么,但我只是想大声说出来。是的。不同进程ID,但会话ID相同。查找将1个会话ID映射到1个用户。因此,使用此方法,具有不同流程用户的多个不同流程将映射到同一用户。