Получить дескриптор окна (IntPtr) из текущего GUID окна веб-драйвера Selenium

Я пытаюсь сделать снимок экрана всего экрана браузера (например, с любыми панелями инструментов, панелями и т. Д.), А не только всей страницы, поэтому у меня есть этот код:

using (FirefoxDriver driver = new FirefoxDriver())
{ 
    driver.Navigate().GoToUrl(url);                

    ScreenCapture sc = new ScreenCapture();

    // How can I find natural IntPtr handle of window here, using GUID-like identifier returning by driver.currentWindowHandle?
    Image img = sc.CaptureWindow(...);
    MemoryStream ms = new MemoryStream();
    img.Save(ms, ImageFormat.Jpeg);
    return new FileStreamResult(ms, "image/jpeg");
}

3 ответа

Вы можете получить дескриптор окна, используя Process.GetProcesses:

using (FirefoxDriver driver = new FirefoxDriver())
{
    driver.Navigate().GoToUrl(url);

    string title = String.Format("{0} - Mozilla Firefox", driver.Title);
    var process = Process.GetProcesses()
        .FirstOrDefault(x => x.MainWindowTitle == title);

    if (process != null)
    {
        var screenCapture = new ScreenCapture();
        var image = screenCapture.CaptureWindow(process.MainWindowHandle);
        // ...
    }
}

Это, конечно, предполагает, что у вас есть один экземпляр браузера с таким конкретным названием.

Просто и идея для взлома. Вы можете использовать методы Reflection, чтобы получить процесс экземпляра firefox. Сначала объявите класс FirefoxDriverEx, унаследованный от FirefoxDriver - для доступа к защищенному двоичному свойству, которое инкапсулирует экземпляр Process:

 class FirefoxDriverEx : FirefoxDriver {
        public Process GetFirefoxProcess() {
            var fi = typeof(FirefoxBinary).GetField("process", BindingFlags.NonPublic | BindingFlags.Instance);
            return fi.GetValue(this.Binary) as Process;
        }
    }

Чем вы можете получить экземпляр процесса для доступа к свойству MainWindowHandle

using (var driver = new FirefoxDriverEx()) {
            driver.Navigate().GoToUrl(url);

            var process = driver.GetFirefoxProcess();
            if (process != null) {
                var screenCapture = new ScreenCapture();
                var image = screenCapture.CaptureWindow(process.MainWindowHandle);
                // ...
            }
        }

Из коробки селен не предоставляет идентификатор процесса драйвера или hwnd браузера, но это возможно. Ниже приведена логика, чтобы получить HWND

  • Когда драйвер инициализируется, получите URL для концентратора и извлеките номер порта
  • Из номера порта найдите идентификатор процесса, который использует этот порт для прослушивания, т.е. PID водителя
  • После навигации из всех экземпляров iexplore найти родительский PID соответствует pid драйвера, то есть pid браузера.
  • Получив Hwnd браузера pid, как только браузер hwnd найден, вы можете использовать win32 api, чтобы вывести селен на передний план.

здесь невозможно выложить полный код, полное рабочее решение (C#), чтобы вывести браузер вперед, есть в моем блоге

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

Другие вопросы по тегам