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?
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?
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();
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()));
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();
}
}
}
}
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();
}
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;
}
To get process id and attempt to kill it you would use Process
class. The methods of interests are:
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.
Out of box, selenium does not expose driver process id or Browser hwnd but it is possible. Below is the logic to get hwnd
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/
you can give a name to the start window, and find the process by name
Driver = new TouchChromeDriver(service, options, TimeSpan.FromSeconds(30));
Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(30);
var conts = GetHashCode();
(Driver as IJavaScriptExecutor).ExecuteScript($"document.title = '{conts}'");
Thread.Sleep(TimeSpan.FromSeconds(1));
var pc = Process.GetProcesses().FirstOrDefault(p => p.MainWindowTitle == $"{conts} - Google Chrome");
if (pc != null)
pidChromeWindow = pc.Id;
pidChromeDriver = service.ProcessId;