Automate of file download in IE 11 using c#

二次信任 提交于 2019-12-04 16:49:36

I was able to download and close the file download dialog box using the below code

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

            }
        }
    }
Chandrasekhar Telkapalli

My approach:

  1. Identify the window by the window title using a windows API call.

    [DllImport("user32.dll"]
    static extern IntPtr FindWindowByCaption
    
  2. Loop through the IE window until we find the Element with "Frame Notification Bar or "Notification Bar" as Window Class Name

  3. Find the Button named "Open" or "Save" and perform the click.

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

Here is the IE 11 code that works. Its a mix of System.Windows.Automation and Win32 API. Could probably get it to work with Win32 unmanaged API's. I used WinID to get the menu's class name and then iterate through its child elements.

IE 11 has this download frame.

We needed to access the Save As from the Save's down arrow.

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

                            }

                        }
                    }
                }


            }
        }
    }

I have achieved in very simple way. Just by using key strokes.
SendKeys.SendWait("%");
SendKeys.SendWait("%{s}");

Hope this will save your lot of time.

I had two IE processes running - the above code was always picking up the wrong 32bit IE process. So, I've merged the answers from multiple StackOverflow questions and wrote the below code to get this done (without the dll imports).

Please note that you need to add a reference to UIAutomationClient in the project - in order to use the AutomationElement method.

    public static void IESaveFile(string title)
    {
        Thread.Sleep(1000);
        //Get the Internet Explorer window handle using the window title
        var ieWindowHandle = Process.GetProcesses().FirstOrDefault(process => process.MainWindowTitle.Contains(title))?.MainWindowHandle;

        var dialogElements = AutomationElement.FromHandle(ieWindowHandle??IntPtr.Zero).FindAll(TreeScope.Children, Condition.TrueCondition);

        foreach (AutomationElement element in dialogElements)
        {
            if (element.Current.ClassName != "Frame Notification Bar") continue;
            var ChildElements = element.FindAll(TreeScope.Children, Condition.TrueCondition);

            foreach (AutomationElement ChildElement in ChildElements)
            {
                // Identify child window with the name Notification Bar or class name DirectUIHWND
                if (ChildElement.Current.Name != "Notification bar" && ChildElement.Current.ClassName != "DirectUIHWND") continue;
                var DownloadCtrls = ChildElement.FindAll(TreeScope.Children, Condition.TrueCondition);
                foreach (AutomationElement ctrlButton in DownloadCtrls)
                    //Now invoke the button click on the 'Save' button
                    if (ctrlButton.Current.Name.ToLower().Equals("save"))
                        ((InvokePattern) ctrlButton.GetCurrentPattern(InvokePattern.Pattern)).Invoke();
            }
        }
    }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!