【发布时间】:2013-09-12 05:57:05
【问题描述】:
在 C# 中,我启动了一个浏览器进行测试,我想获取 PID,以便在我的 winforms 应用程序上我可以杀死任何剩余的已启动的幽灵进程
driver = new FirefoxDriver();
如何获取 PID?
【问题讨论】:
标签: c# selenium webdriver selenium-webdriver pid
在 C# 中,我启动了一个浏览器进行测试,我想获取 PID,以便在我的 winforms 应用程序上我可以杀死任何剩余的已启动的幽灵进程
driver = new FirefoxDriver();
如何获取 PID?
【问题讨论】:
标签: c# selenium webdriver selenium-webdriver 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()));
【讨论】:
Thread.Sleep(TimeSpan.FromSeconds(3));。
看起来更像是一个 C# 问题,而不是特定于 Selenium 的问题。
这是一个非常古老的非确定性答案,如果您想尝试一下,请重新考虑。
我的逻辑是您使用Process.GetProcessesByName Method 获取名称为firefox 的所有进程PID,然后启动FirefoxDriver,然后再次获取进程的PID,比较它们以获得刚刚启动的PID。在这种情况下,特定驱动程序启动了多少进程并不重要(例如,Chrome 启动多个,Firefox 仅启动一个)。
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();
}
}
}
}
【讨论】:
我没有尝试使用 Firefox,但这是使用 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();
}
【讨论】:
尝试使用父进程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;
}
【讨论】:
要获取进程 ID 并尝试杀死它,您可以使用 Process 类。感兴趣的方法有:
通过名称解析进程后,您可以查询它的属性:process.Id 获取 id。请记住,某些浏览器,例如 Google Chrome 有多个正在运行的进程(Chrome 每个选项卡至少有一个正在运行的进程)。所以如果你想杀死它,你需要杀死所有的进程。
【讨论】:
开箱即用,selenium 不会公开驱动程序进程 ID 或浏览器 hwnd,但这是可能的。 下面是获取hwnd的逻辑
这里不可能发布完整代码,将浏览器放在前面的完整工作解决方案(C#)在我的博客上
http://www.pixytech.com/rajnish/2016/09/selenium-webdriver-get-browser-hwnd/
【讨论】:
你可以给启动窗口起一个名字,并通过名字找到进程
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;
【讨论】: