2012-07-17 3 views
8

Sto provando a catturare uno screenshot dell'intero schermo del browser (ad esempio con barre degli strumenti, pannelli e così via) non solo un'intera pagina, quindi ho questo codice:Ottieni handle di finestra (IntPtr) dalla finestra corrente del selenio web GUID

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"); 
} 

risposta

3

si potrebbe ottenere l'handle della finestra utilizzando 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); 
     // ... 
    } 
} 

Questo ovviamente presuppone che una singola istanza del browser con quel titolo specifico.

+0

bel trucco, btw, ma se ci sono due diversi istanze di FireFox con lo stesso titolo? – kseen

+0

@kseen È possibile sostituire ['FirstOrDefault'] (http://msdn.microsoft.com/en-us/library/bb549039) con [' SingleOrDefault'] (http://msdn.microsoft.com/en-us/library/bb549274), in modo che se ci sono due diverse versioni del browser con lo stesso titolo otterrete un'eccezione. Se sei su un banco di prova, puoi affermarlo. –

+0

@PaoloMoretti come posso ottenere la gestione della finestra corrente (finestra esistente che viene aperta manualmente) che non viene aperta dal driver significa che non posso usare driver.getWindowHandle(); –

2

Giusto e un'idea per l'hack. È possibile utilizzare i metodi Reflection per ottenere il processo dell'istanza di firefox. Prima di dichiarare classe FirefoxDriverEx ereditato da FirefoxDriver - per l'accesso protetto proprietà binaria che racchiude un'istanza del processo:

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

di quanto si possa ottenere un'istanza di processo per l'accesso al MainWindowHandle proprietà

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); 
       // ... 
      } 
     } 
+0

Potresti aggiungere altri metodi per trovare finestre in altri browser FireFox, ad es. IE, Chrome, Safari in selenio? Il problema è che non riesco a trovare 'ChromeBinary' o qualcosa come' FireFoxBinary'. – kseen

+0

Questo metodo non è adatto per IE o Chrome perché in questi casi i processi del browser controllano da servizi di selenio esterni come IEDriverServer.exe e chromedriver.exe. Questo metodo si limita e funziona "così com'è". Per trovare il metodo di lavoro è possibile esaminare i sorgenti del driver del selenio e probabilmente creare le proprie versioni. – necrostaz

+0

Quindi, esiste un solo metodo robuts per ottenere un handle della finestra del browser e questo è trovare una finestra usando WinAPI per titolo parziale della finestra? – kseen

0

fuori della scatola, il selenio non lo fa esporre ID processo driver o Browser hwnd ma è possibile. Di seguito è la logica per ottenere hwnd

  • Quando il driver viene inizializzato, ottenere l'url per il mozzo e estrarre il numero di porta
  • Dal numero di porta, trovare l'ID di processo che sta usando questa porta per l'ascolto, vale a dire. PID del driver
  • Dopo la navigazione, da tutte le istanze di iexplore trovare il PID padre corrisponde al pid del driver, cioè il browser pid.
  • Ottieni l'hwnd del browser pid una volta trovato il browser hwnd, puoi usare win32 api per portare il selenio in primo piano.

sua non è possibile inviare il codice completo qui, la soluzione completa di lavoro (C#) per portare il browser di fronte è sul mio blog

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