Find PID of browser process launched by Selenium WebDriver

17,828

Solution 1

Looks more like a C# question, instead of Selenium specific.

This is a very old non-deterministic answer, please reconsider if you want to try this out.

My logic would be you get all process PIDs with the name firefox using Process.GetProcessesByName Method, then start your FirefoxDriver, then get the processes' PIDs again, compare them to get the PIDs just started. In this case, it doesn't matter how many processes have been started by a specific driver (For example, Chrome starts multiple, Firefox only one).

using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Firefox;

namespace TestProcess {
    [TestClass]
    public class UnitTest1 {
        [TestMethod]
        public void TestMethod1() {
            IEnumerable<int> pidsBefore = Process.GetProcessesByName("firefox").Select(p => p.Id);

            FirefoxDriver driver = new FirefoxDriver();
            IEnumerable<int> pidsAfter = Process.GetProcessesByName("firefox").Select(p => p.Id);

            IEnumerable<int> newFirefoxPids = pidsAfter.Except(pidsBefore);

            // do some stuff with PID if you want to kill them, do the following
            foreach (int pid in newFirefoxPids) {
                Process.GetProcessById(pid).Kill();
            }
        }
    }
}

Solution 2

        int _processId = -1;

        var cService = ChromeDriverService.CreateDefaultService();
        cService.HideCommandPromptWindow = true;

        // Optional
        var options = new ChromeOptions();
        options.AddArgument("--headless");

        IWebDriver webdriver = new ChromeDriver(cService, options);
        _processId = cService.ProcessId;

        Console.Write("Process Id : " + _processId);

        webdriver.Navigate().GoToUrl("https://www.google.lk");

        webdriver.Close();
        webdriver.Quit();
        webdriver.Dispose();

Solution 3

var g = Guid.NewGuid();
driver.Navigate().GoToUrl("about:blank");
driver.ExecuteScript($"document.title = '{g}'");
var pid = Process.GetProcessesByName("firefox").First(p => 
p.MainWindowTitle.Contains(g.ToString()));

Solution 4

I didn't try with Firefox, but that is the way that works with Chrome:

        // creating a driver service
        var driverService = ChromeDriverService.CreateDefaultService();
        _driver = new ChromeDriver(driverService);

        //create list of process id
        var driverProcessIds = new List<int> { driverService.ProcessId };

        //Get all the childs generated by the driver like conhost, chrome.exe...
        var mos = new System.Management.ManagementObjectSearcher($"Select * From Win32_Process Where ParentProcessID={driverService.ProcessId}");
        foreach (var mo in mos.Get())
        {
            var pid = Convert.ToInt32(mo["ProcessID"]);
            driverProcessIds.Add(pid);
        }

        //Kill all
        foreach (var id in driverProcessIds)
        {
            System.Diagnostics.Process.GetProcessById(id).Kill();
        }

Solution 5

Try to use parent process id:

  public static Process GetWindowHandleByDriverId(int driverId)
    {
        var processes = Process.GetProcessesByName("chrome")
            .Where(_ => !_.MainWindowHandle.Equals(IntPtr.Zero));
        foreach (var process in processes)
        {
            var parentId = GetParentProcess(process.Id);
            if (parentId == driverId)
            {
                return process;
            }

        }
        return null;
    }

    private static int GetParentProcess(int Id)
    {
        int parentPid = 0;
        using (ManagementObject mo = new ManagementObject($"win32_process.handle='{Id}'"))
        {
            mo.Get();
            parentPid = Convert.ToInt32(mo["ParentProcessId"]);
        }
        return parentPid;
    }
Share:
17,828
user1320651
Author by

user1320651

Updated on July 21, 2022

Comments

  • user1320651
    user1320651 almost 2 years

    In C# I start up a browser for testing, I want to get the PID so that on my winforms application I can kill any remaining ghost processes started

    driver = new FirefoxDriver();
    

    How can I get the PID?

  • Max Young
    Max Young almost 7 years
    This seems like such a better way than the accepted answer because it isn't a brute force way of finding the browsers pid. Also the WebDriver now has a CurrentWindowHandle property so you dont even need to look for all Chromes on the PC.
  • andrew.fox
    andrew.fox over 6 years
    Please, share the code here, as the link doesn't work anymore
  • Kondal
    Kondal over 6 years
    Explain briefly about answer
  • W0nd3r
    W0nd3r over 6 years
    You can simply set title of page via javascript & loop through all browser instances, find unique title you set earlier and find the pid
  • Illidan
    Illidan almost 6 years
    Not deterministic. Other tests running in parallel may create processes between two 'GetProcessesByName' calls
  • juanora
    juanora almost 6 years
    This will kill all the chrome instances even if is not a test or if is another test running on parallel...
  • Merdan Gochmuradov
    Merdan Gochmuradov about 5 years
    Thanks a lot, this worked form me, just had to add Thread.Sleep(TimeSpan.FromSeconds(3)); after setting document title.
  • ElektroStudios
    ElektroStudios almost 5 years
    The 'CurrentWindowHandle' property is of type String, and the value, once casted to Int64, will throw an arithmetic overflow exception when trying to pass it to the IntPtr/UIntPtr constuctor. So that handle does not seem to be a Win32 window handle, thus it will not help to find the process. At least for my Firefox.
  • ElektroStudios
    ElektroStudios almost 5 years
    This should be the accepted answer. The DriverService class is the one that provides info (a PID) to retrieve the process of the current opened browser instance. Very helpful, also when working with multiple instances of a browser. It helped me a lot. Thanks for sharing this answer!
  • Harleyz
    Harleyz over 4 years
    How does this only have one up vote! this is the only answer needed.
  • Daniel Williams
    Daniel Williams almost 4 years
    I agree - this is the best answer. Just voted it up!
  • Reed
    Reed over 3 years
    Certainly correct me if I'm wrong, this only gets the PID of the DriverServer process, not the browser it is associated with.
  • Piotr M.
    Piotr M. over 3 years
    Yes, this returns DriverService process id - the property summary explicitly says that: "Gets the process ID of the running driver service executable" - the answer is misleading
  • TheHitchenator
    TheHitchenator almost 3 years
    Hi Kotyara! Thanks for offering an answer to this question. I see you're new here, so I'll offer some advice - people are more likely to accept an answer and vote it up if there's some explanation as to why and how the proposed solution works. Currently this code snippet may work, but the person using it won't necessarily understand it - which could lead to difficulty debugging and fault finding.
  • Kotyara
    Kotyara almost 3 years
    Hi @TheHitchenator thanks, I will keep this in mind in the future