Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 查找Selenium WebDriver启动的浏览器进程的PID_C#_Selenium_Webdriver_Selenium Webdriver_Pid - Fatal编程技术网

C# 查找Selenium WebDriver启动的浏览器进程的PID

C# 查找Selenium WebDriver启动的浏览器进程的PID,c#,selenium,webdriver,selenium-webdriver,pid,C#,Selenium,Webdriver,Selenium Webdriver,Pid,在C语言中,我启动一个浏览器进行测试,我想得到PID,这样在我的winforms应用程序上,我就可以杀死任何剩余的启动的重影进程 driver = new FirefoxDriver(); 如何获取PID?若要获取进程id并尝试终止它,请使用类。利益衡量的方法有: GetProcessByName 杀死 按名称解析流程后,您可以查询其属性:process.Id以获取Id。请记住,某些浏览器(如Google Chrome)有多个正在运行的流程Chrome每个选项卡至少有一个正在运行的流程。因此,

在C语言中,我启动一个浏览器进行测试,我想得到PID,这样在我的winforms应用程序上,我就可以杀死任何剩余的启动的重影进程

driver = new FirefoxDriver();

如何获取PID?

若要获取进程id并尝试终止它,请使用类。利益衡量的方法有:

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

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

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

我的逻辑是,您使用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();
            }
        }
    }
}

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

初始化驱动程序时,获取集线器的url并提取端口号 从端口号中,找到使用此端口进行侦听的进程id,即驱动程序的PID 导航后,从iexplore的所有实例中查找父PID与驱动程序的PID匹配,即浏览器PID。 获取浏览器pid的Hwnd 一旦找到浏览器hwnd,您就可以使用win32 api将selenium带到前台。 在这里发布完整的代码是不可能的,我的博客上提供了将浏览器放在前面的完整解决方案C


尝试使用父进程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;
    }

我没有尝试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();
        }

这似乎是一种比公认的答案更好的方法,因为它不是一种强力查找浏览器pid的方法。此外,WebDriver现在有一个CurrentWindowHandle属性,因此您甚至不需要在PC上查找所有chrome。这将杀死所有chrome实例,即使不是一个测试或是另一个并行运行的测试……CurrentWindowHandle属性的类型为String,值一旦转换为Int64,将在尝试将算术溢出异常传递给IntPtr/UIntPtr构造函数时引发该异常。因此,该句柄似乎不是Win32窗口句柄,因此它无助于查找进程。至少对于我的Firefox来说是这样。请在这里分享代码,因为链接不再起作用。请简要解释一下答案。您可以通过javascript设置页面标题,并在所有浏览器实例中循环,找到您之前设置的唯一标题,找到PidThank。这对我来说很有效,只需添加Thread.SleepTimeSpan.FromSeconds3;设置文档标题后。不确定。其他并行运行的测试可能会在两个“GetProcessByName”调用之间创建进程。这应该是可接受的答案。DriverService类提供PID信息,以检索当前打开的浏览器实例的进程。非常有用,在使用浏览器的多个实例时也是如此。这对我帮助很大。谢谢分享这个答案!这怎么只有一张赞成票!这是唯一需要的答案。我同意——这是最好的答案。刚刚投票通过了!如果我错了,请一定纠正我,这只获取DriverServer进程的PID,而不是与其关联的浏览器。是的,这将返回DriverService进程id-属性摘要明确表示:获取正在运行的驱动程序服务可执行文件的进程id-答案有误导性
        // 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();
        }
        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();