Jonathan Kittell
Jonathan Kittell

Reputation: 7503

How to kill only processes started by my application

I am using Selenium WebDriver in an application and I have code to kill the webdrivers and browser instances. However, I am thinking that if the user had any IE browsers open before running the application that this code will kill not only the IE processes spawned by my application but also the IE instances that user had open prior to running the application.

Is there a way to track the processes started by my application so I can filter this method to kill only IE processes spawned by my application, or determine that IE driver and browser instance was spawned by my application, or perhaps both?

public void KillAllBrowsersAndWebDrivers()
{

var webDrivers = Process.GetProcessesByName("IEDriverServer").Select(p => p.Id);
var browsers = Process.GetProcessesByName("iexplore").Select(p => p.Id);
var processIds = webDrivers.Concat(browsers);
// do some stuff with PID, if you want to kill them, do the following
foreach (var pid in processIds)
{
    try
    {
        Process.GetProcessById(pid).Kill();
        Logger.Log(Loglevel.Debug, "Kill Process:{0}", pid);
    }
    catch (Exception)
    {
        Logger.Log(Loglevel.Error, "Error killing process: {0}", pid);
    }
}

}

Upvotes: 2

Views: 1603

Answers (2)

user4250079
user4250079

Reputation:

All you would have to do is keep a list of all the processes you've created. this is a very simple process manager. This code is error prone, and there is no exception handling

private static List<Process> processes = new List<Process>();
static void Main(string[] args)
{
    int PID = StoreProcess (yourProcess);
    KillProcess(PID);    
}

/// <summary>
/// Stores the process in a list
/// </summary>
/// <returns>The PID</returns>
/// <param name="prc">The process to be stored</param>
public static int StoreProcess(Process prc)
{
    int PID = prc.Id; // Get the process PID and store it in an int called PID
    processes.Add (prc); // Add this to our list of processes to be kept track of
    return PID; // Return the PID so that the process can be killed/changed at a later time
}

/// <summary>
/// Kills a process
/// </summary>
/// <param name="PID">The PID of the process to be killed.</param>
public static void KillProcess(int PID)
{
    // Search through the countless processes we have and try and find our process
    for (int i = 0; i <= processes.Count; i++) {
        if (processes [i] == null)
        {
            continue; // This segment of code prevents NullPointerExceptions by checking if the process is null before doing anything with it
        }
        if (processes [i].Id == PID) { // Is this our process?
            processes [i].Kill (); // It is! Lets kill it
            while (!processes [i].HasExited) { } // Wait until the process exits
            processes [i] = null; // Mark this process to be skipped the next time around
            return;
        }
    }
    // Couldn't find our process!!!
    throw new Exception ("Process not found!");
}

Advantages:

  • You can keep track of all the processes you've initialized, and terminate them one by one at any time

Drawbacks:

  • I don't believe there is any

Upvotes: 2

Jonathan Kittell
Jonathan Kittell

Reputation: 7503

Another possible solution is to get a list of the processes running BEFORE spawning any new processes. Then just kill the ones that are not in the list of previously running processes.

public void KillOnlyProcessesSpawnedBySelenium()
{
    // get a list of the internet explorer processes running before spawning new processes
    var pidsBefore = Process.GetProcessesByName("iexplore").Select(p => p.Id).ToList();

    var driver = new Driver(Settings);
    var driver1 = driver.InitiateDriver(); // this method creates new   InternetExplorerDriver
    var driver2 = driver.InitiateDriver();
    var driver3 = driver.InitiateDriver();
    driver1.Navigate().GoToUrl("http://google.com");
    driver2.Navigate().GoToUrl("http://yahoo.com");
    driver3.Navigate().GoToUrl("http://bing.com");

    var pidsAfter = Process.GetProcessesByName("iexplore").Select(p => p.Id);

    var newInternetExplorerPids = pidsAfter.Except(pidsBefore);

     // do some stuff with PID, if you want to kill them, do the following
    foreach (var pid in newInternetExplorerPids)
    {
        Debug.WriteLine("Killing pid: {0}", pid);
        Process.GetProcessById(pid).Kill();
    }

    Assert.IsTrue(pidsBefore.Count > 0);
    // determine if each process before the drivers spawned are running
    foreach (var running in pidsBefore.Select(pid => Process.GetProcessById(pid).IsRunning()))
    {
        Assert.IsTrue(running);
    }
}

Here is an extension method to use to determine if a process is still running or not...

public static bool IsRunning(this Process process)
{
    if (process == null) 
        throw new ArgumentNullException("process");

    try
    {
        Process.GetProcessById(process.Id);
    }
    catch (ArgumentException)
    {
        return false;
    }
    return true;
}

Upvotes: 1

Related Questions