简体   繁体   English

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

[英]How do you get the UserName of the owner of a process?

I'm trying to get a list of processes currently owned by the current user ( Environment.UserName ). 我正在尝试获取当前用户当前拥有的进程列表( Environment.UserName )。 Unfortunately, the Process class doesn't have any way of getting the UserName of the user owning a process. 不幸的是, Process类无法获取拥有进程的用户的UserName。

How do you get the UserName of the user which is the owner of a process using the Process class so I can compare it to Environment.UserName ? 如何使用Process类获取用户的用户名,该用户是进程的所有者,因此我可以将其与Environment.UserName进行比较?

If your solution requires a pinvoke , please provide a code example. 如果您的解决方案需要pinvoke ,请提供代码示例。

Thanks, your answers put me on the proper path. 谢谢,您的回答使我走上了正确的道路。 For those who needs a code sample: 对于那些需要代码示例的人:

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

The CodeProject article How To Get Process Owner ID and Current User SID by Warlib describes how to do this using both WMI and using the Win32 API via PInvoke. Warlib的CodeProject文章“ 如何获取进程所有者ID和当前用户SID”描述了如何同时使用WMI和通过PInvoke使用Win32 API来执行此操作。

The WMI code is much simpler but is slower to execute. WMI代码要简单得多,但是执行起来较慢。 Your question doesn't indicate which would be more appropriate for your scenario. 您的问题并未表明哪种方案更适合您的方案。

Props to Andrew Moore for his answer, I'm merely formatting it because it didn't compile in C# 3.5. 向安德鲁·摩尔(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;
}

You might look at using System.Management (WMI). 您可能会使用System.Management(WMI)。 With that you can query the Win32_Process tree. 这样,您可以查询Win32_Process树。

这是标记为“ Win32_Process类的GetOwner方法”的MS链接

You will have a hard time getting the username without being an administrator on the computer. 如果没有计算机管理员,您将很难获得用户名。

None of the methods with WMI, through the OpenProcess or using the WTSEnumerateProcesses will give you the username unless you are an administrator. 除非您是管理员,否则使用WMI,通过OpenProcess或使用WTSEnumerateProcesses的方法都不会为您提供用户名。 Trying to enable SeDebugPrivilege etc does not work either. 尝试启用SeDebugPrivilege等也不起作用。 I have still to see a code that works without being the admin. 我仍然需要查看无需管理员即可工作的代码。

If anyone know how to get this WITHOUT being an admin on the machine it is being run, please write how to do it, as I have not found out how to enable that level of access to a service user. 如果有人在没有管理员身份的情况下知道如何获取此信息,请写该怎么做,因为我还没有找到如何对服务用户启用该级别的访问权限。

You'll need to add a reference to System.Management.dll for this to work. 您需要添加对System.Management.dll的引用才能使其正常工作。

Here's what I ended up using. 这就是我最终使用的内容。 It works in .NET 3.5: 它适用于.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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM