Завершить процессы запущенные системной(текущей) учеткой
От: vaa https://www.youtube.com/playlist?list=PLtrvASfI1KW7VOYRKjglcagQzWLoxlncl
Дата: 10.01.22 10:06
Оценка:
Environment.UserName при вызове из под LocalSystem
равно имя пк + знак $
tasklist /v выдает NT AUTHORITY\СИСТЕМА, т.е. с Environment.UserName вообще никак не стыкуется.
StartInfo не доступен тк процессы были созданы другим процессом.
WMI очень не хочется использовать т.к. он часто ломается и может или подвесить или убить процесс.
Какой самый простой способ определить имя пользователя запустившего процесс?
Re: Завершить процессы запущенные системной(текущей) учеткой
От: 4058  
Дата: 10.01.22 12:30
Оценка: 4 (1)
Здравствуйте, vaa, Вы писали:

vaa>Environment.UserName при вызове из под LocalSystem

vaa>равно имя пк + знак $
vaa>tasklist /v выдает NT AUTHORITY\СИСТЕМА, т.е. с Environment.UserName вообще никак не стыкуется.
vaa>StartInfo не доступен тк процессы были созданы другим процессом.
vaa>WMI очень не хочется использовать т.к. он часто ломается и может или подвесить или убить процесс.
vaa>Какой самый простой способ определить имя пользователя запустившего процесс?

Совсем простого способа нет (по причине соображений безопасности), поэтому если не хочется использовать WMI, то можно воспользоваться WinAPI:


using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;

...

private static string GetProcessUser(Process process)
{
    IntPtr processHandle = IntPtr.Zero;
    try
    {
        OpenProcessToken(process.Handle, 8, out processHandle);
        WindowsIdentity wi = new WindowsIdentity(processHandle);
        string user = wi.Name;
        return user.Contains(@"\") ? user.Substring(user.IndexOf(@"\") + 1) : user;
    }
    catch
    {
        return null;
    }
    finally
    {
        if (processHandle != IntPtr.Zero)
        {
            CloseHandle(processHandle);
        }
    }
}

[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr hObject);

...

foreach (Process p in Process.GetProcesses())
{
     Console.WriteLine("{0}\t{1}", p.ProcessName, GetProcessUser(p));
}


Способ варварский, при нехватке прав (если запуск не под админом), будет попадать в catch и возвращать null для процессов запущенных под другим пользователем.
Проверено на Win7 и Win10.

Подсмотрено здесь
Re: Завершить процессы запущенные системной(текущей) учеткой
От: Mr.Delphist  
Дата: 12.01.22 14:51
Оценка:
Здравствуйте, vaa, Вы писали:

vaa>Какой самый простой способ определить имя пользователя запустившего процесс?


var name = System.Security.Principal.WindowsIdentity.GetCurrent().Name


Даёт то же самое что и whoami из консоли — оно?
Re[2]: Завершить процессы запущенные системной(текущей) учеткой
От: vaa https://www.youtube.com/playlist?list=PLtrvASfI1KW7VOYRKjglcagQzWLoxlncl
Дата: 13.01.22 01:43
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>Здравствуйте, vaa, Вы писали:


vaa>>Какой самый простой способ определить имя пользователя запустившего процесс?


MD>
MD>var name = System.Security.Principal.WindowsIdentity.GetCurrent().Name
MD>


MD>Даёт то же самое что и whoami из консоли — оно?


Да, сделал как в предыдущем совете:
            var login = WindowsIdentity.GetCurrent().Name;
            Try(() => Process.GetProcessesByName(procesName))
                  .Match(processes =>
                  {
                      logger.LogInformation($"{procesName} = {string.Join(", ", processes.Map(p => p.Id.ToString()))}");
                      processes.Iter(process =>
                      {
                          var userName = GetProcessUser(process); // <= winapi (см. 1 ответ)
                          if (string.IsNullOrWhiteSpace(userName) || userName.Equals(login, StringComparison.Ordinal))
                          {
                              Try(() => process.Kill()).Match(_ => output += process.ProcessName + " " + process.Id + " was killed, userName is '" + userName + "';",
                                  exn =>
                                  {


Работает из под localsystem нормально.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.