Click here to Skip to main content
15,884,472 members
Articles / Web Development / ASP.NET
Tip/Trick

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

Rate me:
Please Sign up or sign in to vote.
4.95/5 (8 votes)
1 Aug 2014CPOL2 min read 75.8K   1.3K   16   2
Sometimes we need to kill a process programly. This article talk about how to get process array to process name and filter it.

Image 1

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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Unknown
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionThanks for such good elaboration of topic... Pin
Sasmi_Office7-Oct-14 3:55
Sasmi_Office7-Oct-14 3:55 
Thanks friend,

But i am little bit confused how to know which Excel is not in use.

Let me clear I am facing same issue where my Web Application generate Excel utilize and release the memory by clearing the object using following code but most of the time the excel wont release and facing issue of already open file Exception which not allow user to go further.

All this thing goes on my live server and there we can not get the specific user name for generated Excel (Showing 'Administrator') so how come i kill specific one?

Only can go to kill which is not in use but how to know which one is not in use?

Please help me regarding this.

C#
Excel.Application xlobj = new Excel.ApplicationClass();
Excel.Workbook w;// = new Excel.Workbook();

w = xlobj.Workbooks.Open(path, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, ""
                            , true, false, 0, true, false, false);
s = (Excel.Worksheet)w7.Worksheets.get_Item("Sheet1");

My Excel formatting code goes here

w.Save();
w.Close(true, path8, Type.Missing);
Marshal.ReleaseComObject(w);

xlobj.Quit();
TryKillProcessByMainWindowHwnd(xlobj.Hwnd);
Marshal.ReleaseComObject(xlobj);



Thanks and Regards
Sasmi
GeneralTHANK YOU! Pin
CodeFate1-Aug-14 17:59
professionalCodeFate1-Aug-14 17:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.