Find PID of browser process launched by Selenium WebDriver

梦想与她 提交于 2019-11-29 20:04:19

问题


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?


回答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();
            }
        }
    }
}



回答2:


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()));



回答3:


        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();



回答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();
        }



回答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;
    }



回答6:


To get process id and attempt to kill it you would use Process class. The methods of interests are:

  • GetProcessesByName
  • Kill

Once you resolve a process by name you can query it's property: process.Id for an id. Keep in mind, some browsers, like Google Chrome have several running processes (Chrome has at least one running process per tab). So if you want to kill it, you need to kill all the processes.




回答7:


Out of box, selenium does not expose driver process id or Browser hwnd but it is possible. Below is the logic to get hwnd

  • When driver is initialized, get the url for hub and extract the port number
  • From port number, find the process id which is using this port for listening, ie. PID of driver
  • After navigation, from all instances of iexplore find the parent PID matches the pid of driver, i.e browser pid.
  • Get the Hwnd of browser pid once browser hwnd is found , you can use win32 api to bring selenium to foreground.

its not possible to post full code here, the full working solution (C#) to bring browser in front is on my blog

http://www.pixytech.com/rajnish/2016/09/selenium-webdriver-get-browser-hwnd/



来源:https://stackoverflow.com/questions/18686474/find-pid-of-browser-process-launched-by-selenium-webdriver

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!