tags:

views:

601

answers:

2

Hi,

How to kill specific process running under specific user account. using C#?

Thanks,

+2  A: 
var processes = from p in Process.GetProcessesByName(nameOfTheProcess)
                where p.StartInfo.UserName == nameOfTheUser
                select p;

foreach(Process p in processes) p.Kill();

EDIT: as Fredrik pointed out, the UserName property is not set for processes obtained by GetProcesses. Here's a modified version that uses WMI to get the username (GetProcessOwner method found here) :

static void KillProcessByNameAndUserName(string processName, string userName)
{
    var processes = from p in Process.GetProcessesByName(processName)
                    where GetProcessOwner(p.Id) == userName
                    select p;

    foreach(Process p in processes) p.Kill();
}

static string GetProcessOwner(int processId)
{

    string query = “Select * From Win32_Process Where ProcessID = “ + processId;
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
    ManagementObjectCollection processList = searcher.Get();

    foreach (ManagementObject obj in processList)
    {
        string[] argList = new string[] { string.Empty };
        int returnVal = Convert.ToInt32(obj.InvokeMethod(“GetOwner”, argList));
        if (returnVal == 0)
            return argList[0];
    }

    return “NO OWNER”;

}
Thomas Levesque
Umm.. does that code compile? Looks like it is missing a select in the Linq query. As a side note; I tested a similar approach, but the UserName property of the StartInfo object is an empty string for all processes.
Fredrik Mörk
I added the missing 'select', probably at the same time you posted your comment ;). But you're right about the UserName, it's not set for processes you didn't create yourself... there must be another way
Thomas Levesque
+1: the WMI solution works well for me.
Fredrik Mörk
A: 

In order to get the username, you have to grab the security context of the process from the Win32 API.

Call the OpenProcessToken() function via P/Invoke using the process handle found in the .Net Process class from the code you already have above. You will obtain a structure that contains a SID for the owner of the process. Be prepared for errors such as Access Denied, since you may not have access rights to obtain this information for all processes, such as those that are not yours. From there, you have to convert the SID to a name. There are a few ways to do this, but LookupAccountSid() function (again, via P/Invoke) will get the username for you.

In framework 2.0, a bunch of stuff was added to help with dealing with security descriptors (System.Security.AccessControl namespace), however, I don't see anything that will help you in dealing with the P/Invoke complexities there.

See pinvoke.net for information on using the Win32 API from C#.

Bill