C# 使用c在IE11中自动下载文件#

C# 使用c在IE11中自动下载文件#,c#,watin,C#,Watin,[DllImport("user32.dll"] static extern IntPtr FindWindowByCaption 我正在尝试获取窗口处理程序并按下保存按钮。我在IE8和IE9上找到了几个例子。但该代码在IE11上不起作用 const int BM_CLICK = 0x00F5; [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string l

[DllImport("user32.dll"]
static extern IntPtr FindWindowByCaption
我正在尝试获取窗口处理程序并按下保存按钮。我在IE8和IE9上找到了几个例子。但该代码在IE11上不起作用

    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"]
static extern IntPtr FindWindowByCaption
const int BM\u CLICK=0x00F5;
[DllImport(“user32.dll”,SetLastError=true)]
静态外部IntPtr FindWindow(字符串lpClassName,字符串lpWindowName);
[DllImport(“user32.dll”)]
[返回:Marshallas(UnmanagedType.Bool)]
静态外部bool setforegroundindow(IntPtr hWnd);
[DllImport(“user32.dll”,SetLastError=true)]
静态外部IntPtr SetActiveWindow(IntPtr hWnd);
[DllImport(“user32.dll”,CharSet=CharSet.Auto)]
公共静态外部IntPtr FindWindowEx(IntPtr parent,IntPtr next,字符串sClassName,IntPtr sWindowTitle);
[DllImport(“user32.dll”,SetLastError=true)]
静态外部IntPtr FindWindowEx(IntPtr hwndParent、IntPtr hwndChildAfter、字符串lpszClass、字符串lpszWindow);
[DllImport(“user32.dll”,CharSet=CharSet.Auto)]
静态外部IntPtr发送消息(IntPtr hWnd、UInt32消息、IntPtr wParam、IntPtr LPRAM);
[DllImport(“user32.dll”,ExactSpelling=true,CharSet=CharSet.Auto)]
公共静态外部单元GetDlgCtrlID(IntPtr hWnd);
[DllImport(“user32.dll”,CharSet=CharSet.Auto)]
公共静态外部IntPtr SendMessage(IntPtr hWnd、int msg、int wParam、IntPtr lParam);
//hDialog-对话框窗口的句柄。idBtn-按钮的Id
公共静态布尔单击按钮非对话(IntPtr hDialog,UInt32 idBtn)
{
IntPtr res=IntPtr.0;
单元id;
IntPtr hOkBtn=IntPtr.0;
int尝试=0;
做
{
睡眠(300);
//搜索按钮
hOkBtn=FindWindowEx(hDialog,hOkBtn,“按钮”,IntPtr.Zero);
id=GetDlgCtrlID(hOkBtn);
尝试++;
}while(id!=idBtn&&trunt<20);
如果(!hOkBtn.Equals(IntPtr.Zero))
{
//点击按钮
res=发送消息(hOkBtn,(int)BM_CLICK,1,IntPtr.Zero);
}
if(res.ToInt32()==1)
返回true;
返回false;
}
公共静态void FindAndSave()
{
IntPtr hOkBtn=IntPtr.0;
uint消息=0xf5;
IntPtr hwnd=FindWindow(null,“Internet Explorer”);
hOkBtn=FindWindowEx(hwnd,hOkBtn,“按钮”,“取消”);
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();

            }
        }
    }
[DllImport("user32.dll"]
static extern IntPtr FindWindowByCaption
我的做法:

[DllImport("user32.dll"]
static extern IntPtr FindWindowByCaption
  • 使用windows API调用通过窗口标题标识窗口

    [DllImport("user32.dll"]
    static extern IntPtr FindWindowByCaption
    
  • 在IE窗口中循环,直到找到窗口类名为“Frame Notification Bar”或“Notification Bar”的元素

  • [DllImport("user32.dll"]
    static extern IntPtr FindWindowByCaption
    
  • 找到名为“打开”或“保存”的按钮并执行单击

    [DllImport("user32.dll"]
    static extern IntPtr FindWindowByCaption
    
    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();
                            }
    
                        }
                    }
                }
    
    
            }
        }
    }
    

  • 这是IE11代码。它是System.Windows.Automation和Win32 API的混合体。可能会使它与Win32非托管API一起工作。我过去常常获取菜单的类名,然后遍历其子元素

    [DllImport("user32.dll"]
    static extern IntPtr FindWindowByCaption
    
    IE11有这个下载框架。

    [DllImport("user32.dll"]
    static extern IntPtr FindWindowByCaption
    
    我们需要从Save的向下箭头访问Save-As

    [DllImport("user32.dll"]
    static extern IntPtr FindWindowByCaption
    
        [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}”);

    [DllImport("user32.dll"]
    static extern IntPtr FindWindowByCaption
    

    希望这能节省您的时间。

    我有两个IE进程正在运行-上面的代码总是选择错误的32位IE进程。因此,我合并了多个StackOverflow问题的答案,并编写了下面的代码来完成这项工作(没有dll导入)

    [DllImport("user32.dll"]
    static extern IntPtr FindWindowByCaption
    
    请注意,为了使用AutomationElement方法,您需要在项目中添加对UIAutomationClient的引用

    [DllImport("user32.dll"]
    static extern IntPtr FindWindowByCaption
    
        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();
                }
            }
        }
    

    您是否尝试过使用Autoit之类的工具?powershell是吗?我可以选择任何可以在C中使用的选项,但这不起作用。
    FindWindow
    将不接受值为
    null
    的第一个参数。遗憾的是,它在IE11中不起作用。IE11中没有单独打开的文件下载窗口:/请参阅我的IE 11a答案g of only code永远不是答案。请详细说明。1.第一步是我们将使用windows API调用通过窗口标题来识别窗口。[DllImport(“user32.dll”,EntryPoint=“FindWindow”,SetLastError=true)]静态外部IntPtr FindWindowByCaption(IntPtr ZeroOnly,字符串lpWindowName);我的方法1.我们将使用windows API调用通过窗口标题识别窗口。[DllImport(“user32.dll”]静态外部IntPtr FindWindowByCaption 2.在IE窗口中循环,直到找到带有“框架通知栏”或“通知栏”的自动化元素作为窗口类名3。查找按钮自动化元素的名称“打开”或“保存”,然后执行单击。如何引用此“WindowHandleInfo.FindWindow”非常感谢您提供了这个可靠的解决方案!它工作得非常好!如果其他人也在研究这个问题,我很难让它正常工作,这里有什么帮助:“我一直很难找到WindowsBase,直到我意识到我的目标环境是.NET 2.0,所以作为提醒,请确保您使用的是.NET 4.0或更高版本,以便能够添加该引用。”-krs013 2月5日6:05