2011-09-21 8 views
10

Estoy tratando de probar la descarga de archivos con Watin 2.1.0 contra IE9. He utilizado el código sugerido de la respuesta aceptada a la pregunta Downloading a file with Watin in IE9, así:¿Cómo probar la descarga de archivos con Watin/IE9?

var downloadHandler = new FileDownloadHandler(fname); 
WebBrowser.Current.AddDialogHandler(downloadHandler); 
link.ClickNoWait(); 
downloadHandler.WaitUntilFileDownloadDialogIsHandled(15); 
downloadHandler.WaitUntilDownloadCompleted(200); 

Sin embargo, los downloadHandler.WaitUntilFileDownloadDialogIsHandled(15) llamada agota. ¿Que debería hacer?

+0

¿Intenta esperar más? Para un archivo grande, el diálogo de Descarga de archivos puede tardar un rato en aparecer. 15 segundos no parece lo suficientemente largo –

+0

@Jeremy McGee El archivo es muy pequeño, y he verificado que el cuadro de diálogo de descarga aparece. Incluso lo cancelé manualmente, y WaitUntilFileDownloadDialogIsHandled aún excedió el tiempo de espera. – aknuds1

+0

Intente utilizar DialogHandlerHelper para identificar lo que WATIN piensa que es la ventana de diálogo de descarga de IE9, ya que me parece que el diálogo de descarga de IE9 no cumple con los criterios que WATIN utiliza para encontrarlo. –

Respuesta

8

IE9 ya no utiliza una ventana de diálogo para guardar archivos. En cambio, usa la barra de notificaciones para evitar que el foco se elimine del sitio web. Consulte http://msdn.microsoft.com/en-us/ie/ff959805.aspx en "Administrador de descarga" para referencia.

Desafortunadamente, esto significa que el actual FileDownloadHandler en WatiN no funcionará. Instala una clase "DialogWatcher" por instancia de navegador que es una bomba de mensajes básica para cualquier tipo de ventana secundaria. Cuando se encuentran ventanas secundarias, DialogWatcher comprueba si la ventana es específicamente un diálogo (que no es la barra de notificaciones). Si se trata de un diálogo, entonces itera sobre las instancias de IDialogHandler registradas que llaman "CanHandleDialog". Incluso si la barra de notificaciones era un diálogo, es de un Estilo de ventana diferente (http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx), que es cómo WatiN detecta el tipo de diálogo.

Por lo que puedo ver, todavía no hay soporte para detectar la barra de notificaciones de IE 9 y sus indicaciones en WatiN. Hasta que se agregue esa compatibilidad, no podrá automatizar la descarga de archivos en IE9.

+1

Argh, probablemente tengas razón, aunque no he podido confirmar lo contrario. – aknuds1

+1

El uso de watin 2.1 solo no es posible, pero utilizando el método a continuación sobre UIAutomation *, es posible realizar todos los comandos de la barra amarilla amarilla, incluidos abrir y guardar como. – tomsv

21

El cuadro de diálogo de descarga de archivos no funciona en IE9 (Windows7) NetFramework 4.0.

siguiente fragmento de código podría ayudar a resolver el problema:

Primero se debe agregar referencias UIAutomationClient y UIAutomationTypes a su proyecto de prueba.

Después en Ie9 Herramientas -> Ver Descargas -> Las opciones definen la ruta a su carpeta de guardado.

El siguiente método se extiende la clase Browser

public static void DownloadIEFile(this Browser browser) 
{ 
    // see information here (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633515(v=vs.85).aspx) 
    Window windowMain = new Window(WatiN.Core.Native.Windows.NativeMethods.GetWindow(browser.hWnd, 5)); 
    System.Windows.Automation.TreeWalker trw = new System.Windows.Automation.TreeWalker(System.Windows.Automation.Condition.TrueCondition); 
    System.Windows.Automation.AutomationElement mainWindow = trw.GetParent(System.Windows.Automation.AutomationElement.FromHandle(browser.hWnd)); 

    Window windowDialog = new Window(WatiN.Core.Native.Windows.NativeMethods.GetWindow(windowMain.Hwnd, 5)); 
    // if doesn't work try to increase sleep interval or write your own waitUntill method 
    Thread.Sleep(1000); 
    windowDialog.SetActivate(); 
    System.Windows.Automation.AutomationElementCollection amc = System.Windows.Automation.AutomationElement.FromHandle(windowDialog.Hwnd).FindAll(System.Windows.Automation.TreeScope.Children, System.Windows.Automation.Condition.TrueCondition); 

    foreach (System.Windows.Automation.AutomationElement element in amc) 
    { 
     // You can use "Save ", "Open", ''Cancel', or "Close" to find necessary button Or write your own enum 
     if (element.Current.Name.Equals("Save")) 
     { 
      // if doesn't work try to increase sleep interval or write your own waitUntil method 
      // WaitUntilButtonExsist(element,100); 
      Thread.Sleep(1000); 
      System.Windows.Automation.AutomationPattern[] pats = element.GetSupportedPatterns(); 
      // replace this foreach if you need 'Save as' with code bellow 
      foreach (System.Windows.Automation.AutomationPattern pat in pats) 
      { 
       // '10000' button click event id 
       if (pat.Id == 10000) 
       { 
        System.Windows.Automation.InvokePattern click = (System.Windows.Automation.InvokePattern)element.GetCurrentPattern(pat); 
        click.Invoke(); 
       } 
      } 
     } 
    } 
} 

si desea que haga clic en 'Guardar como' reemplazar código foreach con este

System.Windows.Automation.AutomationElementCollection bmc = element.FindAll(System.Windows.Automation.TreeScope.Children, System.Windows.Automation.Automation.ControlViewCondition); 
System.Windows.Automation.InvokePattern click1 = (System.Windows.Automation.InvokePattern)bmc[0].GetCurrentPattern(System.Windows.Automation.AutomationPattern.LookupById(10000)); 
click1.Invoke(); 
Thread.Sleep(10000); 

System.Windows.Automation.AutomationElementCollection main = mainWindow.FindAll(System.Windows.Automation.TreeScope.Children 
,System.Windows.Automation.Condition.TrueCondition); 
foreach (System.Windows.Automation.AutomationElement el in main) 
{ 
    if (el.Current.LocalizedControlType == "menu") 
    { 
     // first array element 'Save', second array element 'Save as', third second array element 'Save and open' 
     System.Windows.Automation.InvokePattern clickMenu = (System.Windows.Automation.InvokePattern) 
        el.FindAll(System.Windows.Automation.TreeScope.Children,  System.Windows.Automation.Condition.TrueCondition) [1].GetCurrentPattern(System.Windows.Automation.AutomationPattern.LookupById(10000)); 
         clickMenu.Invoke(); 
     //add ControlSaveDialog(mainWindow, filename) here if needed 
     break; 

    } 
} 

Editar: Además, si usted necesita para automatizar el diálogo Guardar como especificando una ruta y haciendo clic en guardar, puede hacerlo agregando este código justo antes del corte;

private static void ControlSaveDialog(System.Windows.Automation.AutomationElement mainWindow, string path) 
{ 
    //obtain the save as dialog 
    var saveAsDialog = mainWindow 
         .FindFirst(TreeScope.Descendants, 
            new PropertyCondition(AutomationElement.NameProperty, "Save As")); 
    //get the file name box 
    var saveAsText = saveAsDialog 
      .FindFirst(TreeScope.Descendants, 
         new AndCondition(
          new PropertyCondition(AutomationElement.NameProperty, "File name:"), 
          new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit))) 
      .GetCurrentPattern(ValuePattern.Pattern) as ValuePattern; 
    //fill the filename box 
    saveAsText.SetValue(path); 

    Thread.Sleep(1000); 
    //find the save button 
    var saveButton = 
      saveAsDialog.FindFirst(TreeScope.Descendants, 
      new AndCondition(
       new PropertyCondition(AutomationElement.NameProperty, "Save"), 
       new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button))); 
    //invoke the button 
    var pattern = saveButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern; 
    pattern.Invoke(); 
} 
+0

Esto es realmente genial, pero ¿se puede automatizar el guardado como diálogo para guardarlo como un nombre de archivo específico? Intenté modificar el código, pero cuando lo busqué, busqué el cuadro de diálogo Guardar como, tengo problemas. – PeteT

+1

Se resolvió automatizar la ruta Guardar como y hacer clic en guardar para agregar el código a su respuesta. Espero que esté bien. – PeteT

+2

¿Puedes publicar un github gist de la solución completa usando Guardar como? Me está resultando difícil conseguir esto para trabajar en IE10. – djbyter

Cuestiones relacionadas