使用c#在IE 11中自动下载文件

在此处输入图像描述

我正在尝试获取窗口处理程序并按“保存”按钮。 我在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); 

我可以使用下面的代码下载并关闭文件下载对话框

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

我的方法:

  1. 使用Windows API调用通过窗口标题标识窗口。

     [DllImport("user32.dll"] static extern IntPtr FindWindowByCaption 
  2. 循环浏览IE窗口,直到我们找到带有“框架通知栏或”通知栏“的元素作为窗口类名称

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

这是IE 11的代码。 它是System.Windows.Automation和Win32 API的混合体。 可能会让它与Win32非托管API一起使用。 我使用WinID获取菜单的类名,然后遍历其子元素。

IE 11有这个下载框架。 在此处输入图像描述

我们需要从Save的向下箭头访问Save As。

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

我以非常简单的方式取得了成就。 只需使用击键。
SendKeys.SendWait( “%”);
SendKeys.SendWait( “%{S}”);

希望这会节省你的大量时间。