【问题标题】:How do you get the UserName of the owner of a process?你如何获得进程所有者的用户名?
【发布时间】:2010-09-22 23:04:58
【问题描述】:

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

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

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

【问题讨论】:

    标签: c# .net process


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

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

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

          如果有人知道如何在不成为正在运行的机器上的管理员的情况下获得此功能,请写下如何操作,因为我还没有找到如何为服务用户启用该级别的访问权限。

          【讨论】:

          • 检查了那个。问题是它获取会话的用户名。如果我用 2 个不同的用户打开 2 个 CMD 窗口,它们都具有相同的 Session ID (2)。两者都解析为同一个用户,这是错误的。任务管理器正确显示它们。
          • 我已经远离这个问题了,但他们不会有不同的 ProcID 吗?不记得它返回了什么,但只是在这里大声思考。
          • 是的。 Diff proc Id 但相同的会话 ID。查找将 1 个会话 ID 映射到 1 个用户。所以几个不同进程用户的不同进程会用这种方法映射到同一个用户。
          【解决方案5】:

          Warlib 的 CodeProject 文章 How To Get Process Owner ID and Current User SID 描述了如何同时使用 WMI 和通过 PInvoke 使用 Win32 API 来执行此操作。

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

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              【解决方案7】:

              您可能会考虑使用 System.Management (WMI)。这样你就可以查询 Win32_Process 树了。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2017-11-10
                • 1970-01-01
                • 2011-06-03
                • 2017-12-04
                • 1970-01-01
                • 2020-01-01
                • 1970-01-01
                相关资源
                最近更新 更多