Как вы получаете UserName владельца процесса?
Я пытаюсь получить список процессов, принадлежащих текущему пользователю (Environment.UserName
). К сожалению, класс Process
не имеет никакого способа получить UserName пользователя, которому принадлежит процесс.
Как вы получаете UserName пользователя, который является владельцем процесса, используя класс Process
, чтобы я мог сравнить его с Environment.UserName
?
Если вашему решению требуется pinvoke
, укажите пример кода.
Ответы
Ответ 1
Статья CodeProject Как получить идентификатор владельца процесса и текущий SID пользователя с помощью Warlib описывает, как это сделать, используя WMI и используя API Win32 через PInvoke.
Код WMI намного проще, но выполняется медленнее. В вашем вопросе не указывается, что было бы более подходящим для вашего сценария.
Ответ 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
Вы можете посмотреть на использование System.Management(WMI). С этим вы можете запросить дерево Win32_Process.
Ответ 4
вот ссылка MS, помеченная как "Метод GetOwner класса Win32_Process"
Ответ 5
Вам будет сложно получить имя пользователя, не будучи администратором на компьютере.
Ни один из методов с WMI через OpenProcess или использование WTSEnumerateProcesses не даст вам имя пользователя, если вы не являетесь администратором. Попытка включить SeDebugPrivilege и т.д. Тоже не работает. Я все еще вижу код, который работает без администратора.
Если кто-то знает, как получить это БЕЗ администратора на машине, он запускается, напишите, как это сделать, поскольку я не узнал, как включить этот уровень доступа к пользователю службы.
Ответ 6
Подтверждает Эндрю Мур за его ответ, я просто форматирую его, потому что он не компилировался на С# 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;
}
Ответ 7
Для этого вам нужно добавить ссылку на 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);
}
}