Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to kill process by process name and user name using C#?

0.00/5 (No votes)
1 Aug 2014 1  
Sometimes we need to kill a process programly. This article talk about how to get process array to process name and filter it.

Introduction

Sometimes we need to kill a process programatically. For example, in above screenshot, we need to kill the process "EXCEL.EXE", which belongs to user "appdev01", but not to kill other processes which belongs to other users. This article talk about how to use C# to get process by name, and then filter it by user name and process start time.

Background

The background that I write this article has something to do with one of the projects that I am doing. In my this project, I created a web page, allowing internal users to upload a contract in a pre-defined format of EXCEL file. And then my program will open the EXCEL file, and load the contract to our several systems.

You know that after finish everything, my program needs to close the EXCEL file, release all resources. I used methods to release the resources, and it can work, but cannot work 100%. That means sometimes work, sometimes not.

     // close WorkBook
    wb.Close(false, NewFileNameFull, Missing.Value);
    ap.Quit();
    System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(ap);

I also tried many other methods, they also work but none of them can work every time. In internet, many people discuss this issue, but there is no complete solution. So we need to log on the server, launch task manager, and kill the process manually.

The best solution should be use C# code, to kill the process automatically.

Using the Code

At here, I write a class ProcessHelper, with a public method KillProcessByNameAndUser. It is easy to use. Below is an example code to use it.

    ProcessHelper.ProcessHelper ph = new ProcessHelper.ProcessHelper();
    ph.KillProcessByNameAndUser("EXCEL", "myPCName\appdev01", 12);

At here, it finds the "EXCEL" processes, which started 12 hours ago and belongs to a local user "appdev01" in the machine "myPCName", and kill them.

Below is the source code of the class

using System;
using System.Management;
using System.Diagnostics;

namespace ProcessHelper
{
    public class ProcessHelper
    {

        public 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, string.Empty };
                int returnVal = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList));
                if (returnVal == 0)
                {
                    return argList[1] + "\\" + argList[0];   // return DOMAIN\user
                }
            }
            return "NO OWNER";
        }

        /// <summary>
        /// Kill processes if they meet the parameter values of process name, owner name, expired started times.
        /// </summary>
        /// <param name="ProcessName">Process Name, case sensitive, for emample "EXCEL" could not be "excel"</param>
        /// <param name="ProcessUserName">Owner name or user name of the process, casse sensitive</param>
        /// <param name="HasStartedForHours">if process has started for more than n (parameter input) hours. 0 means regardless how many hours ago</param>
        public void KillProcessByNameAndUser(string ProcessName, string ProcessUserName, int HasStartedForHours)
        {
            Process[] foundProcesses = Process.GetProcessesByName(ProcessName);
            Console.WriteLine(foundProcesses.Length.ToString() + " processes found.");
            string strMessage = string.Empty;
            foreach (Process p in foundProcesses)
            {
                string UserName = GetProcessOwner(p.Id);
                strMessage = string.Format("Process Name: {0} | Process ID: {1} | User Name : {2} | StartTime {3}",
                                                 p.ProcessName, p.Id.ToString(), UserName, p.StartTime.ToString());
                //Console.WriteLine(strMessage);
                bool TimeExpired = (p.StartTime.AddHours(HasStartedForHours) < DateTime.Now) || HasStartedForHours == 0;
                bool PrcoessUserName_Is_Matched = UserName.Equals(ProcessUserName);

                if ((ProcessUserName.ToLower() == "all" && TimeExpired) ||
                     PrcoessUserName_Is_Matched && TimeExpired)
                {
                    p.Kill();
                    //Console.WriteLine("Process ID " + p.Id.ToString() + " is killed.");
                }
            }
        }
    }
}

Note: If you use the code and face a compile error for Using System.Management; you need to add reference to the System.Management object.

Points of Interest

Windows has a built-in command "TASKKILL" to kill a process. For example, below command can also kill the EXCEL process which belongs to user appdev01.

     TASKKILL /F /FI "USERNAME eq APPDEV01" /IM EXCEL.EXE

But our class is more flexible, it can filter by process running time.

And we can also add logic to filter the process's main window title by the property MainWindowTitle.

History

This is the initial version of the class ProcessHelper. In the future, we might add more logics into this function, and I will keep this post updated.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here