How do you kill a process for a particular user in .NET (C#)?

11,190

Solution 1

Ok, here's what I ended up doing:

           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.");
            }

            }

Solution 2

Instead of using GetProcessInfoByPID, I just grab the data from 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();
                }
            }
        }
    }
}

Solution 3

Read the following CodeProject article, it has all the information you need:

How To Get Process Owner ID and Current User SID

Share:
11,190
fr0man
Author by

fr0man

Updated on June 16, 2022

Comments

  • fr0man
    fr0man almost 2 years

    I work off of a multi-user Windows Server, and the rdpclip bug bites us all daily. We usually just open task manager and kill then restart rdpclip, but that's a pain in the butt. I wrote a powershell script for killing then restarting rdpclip, but no one's using it because it's a script (not to mention the execution policy is restricted for the box). I'm trying to write a quick and dirty windows app where you click a button to kill rdpclip and restart it. But I want to restrict it to the current user, and can't find a method for the Process class that does this. So far, here's what I have:

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

    I'm not certain, but I think that's going to kill all the rdpclip processes. I'd like to select by user, like my powershell script does:

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

    I suppose I could just invoke the powershell script from my executable, but that seems fairly kludgy.

    Apologies in advance for any formatting issues, this is my first time here.

    UPDATE: I also need to know how to get the current user and select only those processes. The WMI solution proposed below doesn't help me get that.

    UPDATE2: Ok, I've figured out how to get the current user, but it doesn't match the process user over Remote Desktop. Anyone know how to get username instead of the SID?

    Cheers, fr0man

  • fr0man
    fr0man over 15 years
    Looks good, except I can't get VS to recognized ObjectQuery, even with a Using System.Management. This is an area I'm wholly unfamiliar with.
  • fr0man
    fr0man over 15 years
    Ah, nevermind. That's only supported in .NET 2.0 and below. Fixed now.
  • BobbyShaftoe
    BobbyShaftoe over 15 years
    Personally, I would go the Win32/PInvoke route rather than WMI in this case. However, that's just preference, I think the WMI method would work just as well.
  • Mauricio Scheffer
    Mauricio Scheffer about 14 years
    I had to replace WindowsIdentity.GetCurrent().Name with WindowsIdentity.GetCurrent().User.Value for this to work.