9

在 C# 中,我启动了一个浏览器进行测试,我想获取 PID,以便在我的 winforms 应用程序上我可以杀死任何剩余的已启动的幽灵进程

driver = new FirefoxDriver();

我怎样才能得到PID?

4

8 回答 8

13
        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();
于 2018-04-18T08:32:30.920 回答
12

看起来更像是一个 C# 问题,而不是特定于 Selenium 的问题。

这是一个非常古老的非确定性答案,如果您想尝试一下,请重新考虑。

我的逻辑是您firefox使用Process.GetProcessesByName Method获取所有具有名称的进程 PID ,然后启动您FirefoxDriver的 PID,然后再次获取进程的 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();
            }
        }
    }
}
于 2013-09-09T00:58:17.907 回答
12
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()));
于 2017-08-30T03:28:17.067 回答
6

我没有尝试使用 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();
        }
于 2017-12-13T07:07:44.500 回答
1

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;
    }
于 2016-12-28T11:14:23.447 回答
0

要获取进程 ID 并尝试杀死它,您将使用Processclass. 兴趣的方法是:

  • 按名称获取进程

通过名称解析进程后,您可以查询它的属性:process.Id获取 id。请记住,某些浏览器,例如 Google Chrome 有多个正在运行的进程(Chrome 每个选项卡至少有一个正在运行的进程)。所以如果你想杀死它,你需要杀死所有的进程。

于 2013-09-08T17:41:31.423 回答
0

开箱即用,selenium 不会公开驱动程序进程 ID 或浏览器 hwnd,但它是可能的。以下是获取 hwnd 的逻辑

  • 初始化驱动程序时,获取集线器的 url 并提取端口号
  • 从端口号中,找到正在使用该端口进行侦听的进程ID,即。驱动程序PID
  • 导航后,从所有 iexplore 实例中找到父 PID 匹配驱动程序的 pid,即浏览器 pid。
  • 找到浏览器 hwnd 后获取浏览器 pid 的 Hwnd,您可以使用 win32 api 将 selenium 带到前台。

不可能在这里发布完整的代码,将浏览器放在前面的完整工作解决方案(C#)在我的博客上

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

于 2016-09-09T08:59:03.160 回答
0

您可以为启动窗口命名,并按名称查找进程

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;
于 2021-07-20T13:34:07.260 回答