2011-09-21 10 views
10

私はIE9に対してWatin 2.1.0でファイルのダウンロードをテストしようとしています。Watin/IE9でファイルをダウンロードする方法は?

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

しかし、downloadHandler.WaitUntilFileDownloadDialogIsHandled(15)コールがタイムアウト:私はこのように、質問Downloading a file with Watin in IE9に受け入れ答えから提案されたコードを使用しました。私は何をすべきか?

+0

長くお待ちください。大きなファイルの場合、[ファイルのダウンロード]ダイアログに時間がかかることがあります。 15秒が長く見えない –

+0

@Jeremy McGeeファイルが非常に小さく、ダウンロードダイアログが表示されることを確認しました。私もそれを手動でキャンセルし、WaitUntilFileDownloadDialogIsHandledはまだタイムアウトしました。 – aknuds1

+0

DialogHandlerHelperを使用して、IE9のダウンロードダイアログがWATINが使用する条件を肉付けしていないと感じるので、WATINが実際にIE9ダウンロードダイアログウィンドウをどのように考えるかを確認してください。 –

答えて

8

IE9はファイルの保存にダイアログウィンドウを使用しなくなりました。代わりに、通知バーを使用してWebサイトからフォーカスが削除されないようにします。参考資料として、「Download Manager」のhttp://msdn.microsoft.com/en-us/ie/ff959805.aspxを参照してください。

残念ながら、WatiNの現在のFileDownloadHandlerは機能しません。これは、任意の種類の子ウィンドウの基本的なメッセージポンプであるブラウザインスタンスごとに "DialogWatcher"クラスをインスタンス化します。子ウィンドウに遭遇すると、DialogWatcherはそのウィンドウが特にダイアログ(通知バーではない)であるかどうかをチェックします。ダイアログの場合は、 "CanHandleDialog"を呼び出す登録されたIDialogHandlerインスタンスを反復処理します。通知バーがダイアログであっても、それは異なるウィンドウスタイル(http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx)であり、WatiNがダイアログのタイプを検出する方法です。

私は、IE 9通知バーとWatiNでのプロンプトを検出するためのサポートはまだありません。そのサポートが追加されるまで、IE9でのファイルのダウンロードを自動化することはできません。

+1

そうですね、私はそれ以外のことは確認できませんでしたが、あなたはおそらく正しいでしょう。 – aknuds1

+1

watin 2.1のみを使用することはできませんが、UIAutomation *に関する以下の方法を使用すると、openとsave-asを含むすべてのyellow-white-barコマンドを実行することができます。 – tomsv

21

IE9(Windows7)NetFramework 4.0ではファイルのダウンロードダイアログが動作しません。

まず、あなたのテストプロジェクトへの参照UIAutomationClientとUIAutomationTypesを追加する必要があります。

次のコードスニペットは、あなたが問題を解決するのに役立つかもしれません。

After In Tools - > View Downloads - > Optionsは、保存フォルダへのパスを定義します。 をまた、あなたが名前を付けて保存]ダイアログ自動化する必要がある場合:あなたはこの

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; 

    } 
} 

編集してforeachのコードを置き換え」として保存]をクリックしたい場合

は、次の方法は、ブラウザのクラス

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

を拡張しますパスを指定して[保存]をクリックすると、ブレークの直前にこのコードを追加することができます。

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

これは本当にクールですが、保存ダイアログを自動化して特定のファイル名として保存することはできますか?私はコードを修正しようとしましたが、私が問題を抱えている名前を付けて保存ダイアログを見つけるために見てみるとき。 – PeteT

+1

パスとして保存を自動化して保存をクリックすると、答えにコードが追加されました。希望は大丈夫です。 – PeteT

+2

名前を付けて保存を使用して完全なソリューションのgithubの要点を投稿できますか?私はこれをIE10で動かすのに苦労しています。 – djbyter

関連する問題