Как убить процесс для конкретного пользователя в .NET (C#)?

Я работаю на многопользовательском Windows Server, и ошибка rdpclip ежедневно укусывает нас всех. Обычно мы просто открываем диспетчер задач и убиваем, а затем перезапускаем rdpclip, но это уже неудобно. Я написал сценарий PowerShell для уничтожения, а затем перезапуска rdpclip, но никто его не использует, потому что это сценарий (не говоря уже о том, что политика выполнения ограничена для коробки). Я пытаюсь написать быстрое и грязное приложение для Windows, в котором вы нажимаете кнопку, чтобы убить rdpclip и перезапустить его. Но я хочу ограничить его доступ к текущему пользователю и не могу найти метод для класса Process, который делает это. Пока вот что у меня есть:

Process[] processlist = Process.GetProcesses();
foreach(Process theprocess in processlist)
{
    if (theprocess.ProcessName == "rdpclip")
    {
      theprocess.Kill();
      Process.Start("rdpclip");
    }
}

Я не уверен, но думаю, что это убьет все процессы rdpclip. Я хотел бы выбрать по пользователю, как это делает мой сценарий PowerShell:

taskkill /fi "username eq $env:username" /im rdpclip.exe
& rdpclip.ex

Полагаю, я мог бы просто вызвать сценарий PowerShell из своего исполняемого файла, но это кажется довольно неуклюжим.

Заранее извиняюсь за любые проблемы с форматированием, я здесь впервые.

ОБНОВЛЕНИЕ: мне также нужно знать, как получить текущего пользователя и выбрать только эти процессы. Предлагаемое ниже решение WMI мне не помогает.

ОБНОВЛЕНИЕ 2: Хорошо, я понял, как получить текущего пользователя, но он не соответствует пользователю процесса через удаленный рабочий стол. Кто-нибудь знает, как получить имя пользователя вместо SID?

Ваше здоровье, fr0man

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
7
0
10 467
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Прочтите следующую статью CodeProject, в ней есть вся необходимая информация:

How To Get Process Owner ID and Current User SID

Выглядит хорошо, за исключением того, что я не могу заставить VS распознавать ObjectQuery даже с использованием System.Management. Я совершенно незнаком с этой областью.

fr0man 09.01.2009 03:32

Да ладно. Это поддерживается только в .NET 2.0 и ниже. Исправлено сейчас.

fr0man 09.01.2009 03:35

Лично я бы выбрал путь Win32 / PInvoke, а не WMI в этом случае. Однако это всего лишь предпочтение, я думаю, что метод WMI тоже подойдет.

BobbyShaftoe 09.01.2009 04:10
Ответ принят как подходящий

Хорошо, вот что я в итоге сделал:

           Process[] processlist = Process.GetProcesses();
            bool rdpclipFound = false;

            foreach (Process theprocess in processlist)
            {
                String ProcessUserSID = GetProcessInfoByPID(theprocess.Id);
                String CurrentUser = WindowsIdentity.GetCurrent().Name.Replace("SERVERNAME\\",""); 

                if (theprocess.ProcessName == "rdpclip" && ProcessUserSID == CurrentUser)
                {
                    theprocess.Kill();
                    rdpclipFound = true;
                }

            }
            Process.Start("rdpclip");
            if (rdpclipFound)
            {
               MessageBox.Show("rdpclip.exe successfully restarted"); }
            else
            {
               MessageBox.Show("rdpclip was not running under your username.  It has been started, please try copying and pasting again.");
            }

            }

Мне пришлось заменить WindowsIdentity.GetCurrent (). Name на WindowsIdentity.GetCurrent (). User.Value, чтобы это работало.

Mauricio Scheffer 08.02.2010 15:22

Вместо использования GetProcessInfoByPID я просто беру данные из StartInfo.EnvironmentVariables.

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Security.Principal;
using System.Runtime.InteropServices;

namespace KillRDPClip
{
    class Program
    {
        static void Main(string[] args)
        {
            Process[] processlist = Process.GetProcesses();
            foreach (Process theprocess in processlist)
            {
                String ProcessUserSID = theprocess.StartInfo.EnvironmentVariables["USERNAME"];
                String CurrentUser = Environment.UserName;
                if (theprocess.ProcessName.ToLower().ToString() == "rdpclip" && ProcessUserSID == CurrentUser)
                {
                    theprocess.Kill();
                }
            }
        }
    }
}

Вы можете открыть cmd в скрытом режиме и убить процесс, специфичный для пользователя. Здесь я пытаюсь убить процесс Excel, специфичный для текущего пользователя:

            String CurrentUser = Environment.UserName;
            Process[] allExcelProcesses = Process.GetProcessesByName("excel");
            if (null != allExcelProcesses)
            {
                Process process = new Process();
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                startInfo.FileName = "cmd.exe";
                startInfo.Arguments = "/C TASKKILL /F /FI \"USERNAME eq " + CurrentUser + "\" /IM EXCEL.EXE";
                process.StartInfo = startInfo;
                process.Start();
                process.WaitForExit();
            }

Другие вопросы по теме