2015-06-04 2 views
1

enter image description hereАвтоматизировать из загрузки файлов в IE 11, используя C#

Я пытаюсь получить обработчик окна и нажмите кнопку Сохранить. Я нашел пару примеров на IE8 & 9. Но этот код не работает на IE 11.

const int BM_CLICK = 0x00F5; 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 

    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    static extern bool SetForegroundWindow(IntPtr hWnd); 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr SetActiveWindow(IntPtr hWnd); 

    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr next, string sClassName, IntPtr sWindowTitle); 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 

    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); 



    [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] 
    public static extern uint GetDlgCtrlID(IntPtr hWnd); 

    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam); 

     //hDialog - handle of dialog window. idBtn - Id of button 
     public static bool ClickButtonOnDialog(IntPtr hDialog, UInt32 idBtn) 
     { 
      IntPtr res = IntPtr.Zero; 
      uint id; 
      IntPtr hOkBtn = IntPtr.Zero; 
      int attempt = 0; 
      do 
      { 
       Thread.Sleep(300); 
       //searching for button 
       hOkBtn = FindWindowEx(hDialog, hOkBtn, "Button", IntPtr.Zero); 
       id = GetDlgCtrlID(hOkBtn); 
       attempt++; 
      } while (id != idBtn && attempt < 20); 
      if (!hOkBtn.Equals(IntPtr.Zero)) 
      { 
       //click the button 
       res = SendMessage(hOkBtn, (int)BM_CLICK, 1, IntPtr.Zero); 
      } 
      if (res.ToInt32() == 1) 
       return true; 
      return false; 
     } 

     public static void FindAndSave() 
     { 
      IntPtr hOkBtn = IntPtr.Zero; 
      uint message = 0xf5; 

      IntPtr hwnd = FindWindow(null, "Internet Explorer"); 
      hOkBtn = FindWindowEx(hwnd, hOkBtn, "Button", "Cancel"); 
      SendMessage(hOkBtn, (int)message, 1, IntPtr.Zero); 
+0

Вы пытались использовать такой инструмент, как Autoit? –

+0

Является ли powershell [опция] (http://stackoverflow.com/questions/26024236/powershell-download-file-from-website-ie-document-method)? – lloyd

+0

Я вариант любой опции, которая может использоваться в C# –

ответ

1

Я был в состоянии загрузить и закрыть диалоговое окно загрузки файла, используя приведенный ниже код

[DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 



    static void DownLoadFile(IE browser) 
    { 
     browser.Link(Find.ByText("download")).ClickNoWait(); 

     Thread.Sleep(1000); 
     AutomationElementCollection dialogElements = AutomationElement.FromHandle(FindWindow(null, "Internet Explorer")).FindAll(TreeScope.Children, Condition.TrueCondition); 
     foreach (AutomationElement element in dialogElements) 
     { 
      if (element.Current.Name.Equals("Save")) 
      { 
       var invokePattern = element.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern; 
       invokePattern.Invoke(); 

      } 
     } 
    } 
+0

Это не сработает. 'FindWindow' не примет первый аргумент со значением' null'. –

+0

К сожалению, в IE11 работать не будет. Нет отдельного окна, открытого для загрузки файлов в IE11:/ – AutomationNation

+0

См. Мой ответ для IE 11 – chdev77

1

Мой подход:

  1. Определить окно в заголовок окна с помощью вызова Windows API.

    [DllImport("user32.dll"] 
    static extern IntPtr FindWindowByCaption 
    
  2. Loop через окно IE, пока мы не найдем элемент с «Frame Notification Bar или "Notification Bar" в качестве окна Class Name

  3. Найти кнопку под названием "Открыть" или "Сохранить" и выполнить щелчок.

    public void DownLoadFile(string strWindowTitle) 
    { 
        IntPtr TargetHandle = FindWindowByCaption(IntPtr.Zero, strWindowTitle); 
        AutomationElementCollection ParentElements = AutomationElement.FromHandle(TargetHandle).FindAll(TreeScope.Children, Condition.TrueCondition); 
        foreach (AutomationElement ParentElement in ParentElements) 
        { 
         // Identidfy Download Manager Window in Internet Explorer 
         if (ParentElement.Current.ClassName == "Frame Notification Bar") 
         { 
          AutomationElementCollection ChildElements = ParentElement.FindAll(TreeScope.Children, Condition.TrueCondition); 
          // Idenfify child window with the name Notification Bar or class name as DirectUIHWND 
          foreach (AutomationElement ChildElement in ChildElements) 
          { 
           if (ChildElement.Current.Name == "Notification bar" || ChildElement.Current.ClassName == "DirectUIHWND") 
           { 
    
            AutomationElementCollection DownloadCtrls = ChildElement.FindAll(TreeScope.Children, Condition.TrueCondition); 
            foreach (AutomationElement ctrlButton in DownloadCtrls) 
            { 
             //Now invoke the button click whichever you wish 
             if (ctrlButton.Current.Name.ToLower() == "save") 
             { 
              var invokePattern = ctrlButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern; 
              invokePattern.Invoke(); 
             } 
    
            } 
           } 
          } 
    
    
         } 
        } 
    } 
    
+1

Ответ, состоящий только из кода, никогда не является ответом. Пожалуйста, дополните. – SubliemeSiem

+0

1. Первый шаг - мы будем идентифицировать окно по названию окна, используя вызов API Windows. [DllImport («user32.dll», EntryPoint = «FindWindow», SetLastError = true)] static extern IntPtr FindWindowByCaption (IntPtr ZeroOnly, строка lpWindowName); –

+0

Просто отредактируйте свой пост, не уточняйте в комментарии. – SubliemeSiem

0

Вот IE 11 код, который работает. его смесь System.Windows.Automation и Win32 API. Может, вероятно, заставить его работать ш с неуправляемым API-интерфейсом Win32. Я использовал WinID, чтобы получить имя класса меню, а затем повторить его дочерние элементы.

В IE 11 есть эта рамка для скачивания. enter image description here

Нам нужно было получить доступ к значению «Сохранить как» со стрелки вниз.

[DllImport("user32.dll", SetLastError = true)] 
    public static extern IntPtr FindWindow(string className, string windowTitle); 

    public static void IeDownLoadSaveAs(string windowTitle = null) 
    { 
     if (windowTitle == null) 
      windowTitle = "https://googledownload.com - Internet Explorer"; 
     //get the message handle 
     //the last param "Untitled...is the title of the window and it must match 
     IntPtr parentHandle = WindowHandleInfo.FindWindow("IEFrame", windowTitle); 

     var parentElements = AutomationElement.FromHandle(parentHandle).FindAll(TreeScope.Children, Condition.TrueCondition); 

     foreach (AutomationElement parentElement in parentElements) 
     { 
      // Identidfy Download Manager Window in Internet Explorer 
      if (parentElement.Current.ClassName == "Frame Notification Bar") 
      { 
       var childElements = parentElement.FindAll(TreeScope.Children, Condition.TrueCondition); 
       // Idenfify child window with the name Notification Bar or class name as DirectUIHWND 
       foreach (AutomationElement childElement in childElements) 
       { 
        if (childElement.Current.Name == "Notification bar" || childElement.Current.ClassName == "DirectUIHWND") 
        { 

         var downloadCtrls = childElement.FindAll(TreeScope.Descendants, Condition.TrueCondition); 
         foreach (AutomationElement ctrlButton in downloadCtrls) 
         { 
          //Now invoke the button click whichever you wish 
          if (ctrlButton.Current.Name.ToLower() == "") 
          { 
           var saveSubMenu = ctrlButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern; 
           saveSubMenu.Invoke(); 

           var saveMenuHandle = WindowHandleInfo.FindWindow("#32768", ""); 
           var subMenuItems = AutomationElement.FromHandle(saveMenuHandle).FindAll(TreeScope.Children, Condition.TrueCondition); 

           foreach (AutomationElement item in subMenuItems) 
           { 
            if (item.Current.Name.ToLower() == "save as") 
            { 
             var saveAsMenuItem = item.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern; 
             saveAsMenuItem.Invoke(); 
            } 
           } 

          } 

         } 
        } 
       } 


      } 
     } 
    }