C# WebBrowser控件未响应InvokeMember(“单击”)

C# WebBrowser控件未响应InvokeMember(“单击”),c#,javascript,webbrowser-control,C#,Javascript,Webbrowser Control,在度过了5天的生命后,我打算放弃这一点,但在此之前我咨询过一次专家 我有一个WebBrowser控件,用于加载网页,并通过编程方式刮取其内容。在IE(或任何其他浏览器)中完成后,单击页面中的特定菜单项将打开“文件打开”对话框。但是使用InvokeMember()在WebBrowser控件中单击同一个按钮显然没有任何作用。我已经经历了几个这样的问题,比如确保我的控制行为与IE完全一样,但这并没有成功 我甚至检查了按钮在幕后执行的实际javascript函数,并使用HtmlDocument.Invo

在度过了5天的生命后,我打算放弃这一点,但在此之前我咨询过一次专家

我有一个WebBrowser控件,用于加载网页,并通过编程方式刮取其内容。在IE(或任何其他浏览器)中完成后,单击页面中的特定菜单项将打开“文件打开”对话框。但是使用
InvokeMember()
在WebBrowser控件中单击同一个按钮显然没有任何作用。我已经经历了几个这样的问题,比如确保我的控制行为与IE完全一样,但这并没有成功

我甚至检查了按钮在幕后执行的实际javascript函数,并使用
HtmlDocument.InvokeScript()
手动调用了它,但没有这样做,因为底层函数的参数为
MouseEvent
类型(实际上是click事件)我不确定如何在C#中创建该对象

另一种方法是将焦点设置到该特定按钮,然后尝试
SendKeys
,但这不起作用,因为WebBrowser控件不可见。它只是一个内存中的实例。更具体地说,WebBrowser

编辑 根据读者的要求,以下是我用来查找元素的简单代码:

var MyButton = WB.Document.GetElementById("processfilelink");
processfilelink
是一个锚定标记(
),我已经确认该元素实际上存在于文档主体中。该网页使用jQuery的
委托
功能将该锚的
单击
事件绑定到目标函数。找到按钮后,我只需调用
InvokeMember()
,如下所示:

MyButton.InvokeMember("click");
注意:我还在页面代码中看到mousedown、mouseup和focus事件的绑定。我希望在调用
单击时自动触发所有这些事件,但为了确保我也为这些事件添加了
InvokeMember
调用。结果也没有好转。

从评论中可以看出:

。。。在完整IE浏览器中加载此页面,使用F12工具进行调试并 在JavaScript控制台中执行按钮。单击()。它是否按预期工作 这边

你试过了,结果是:

。。。这很有趣。它不起作用!但是点击这个项目 用手确实可以完美地工作。这是怎么回事

我怀疑as
MyButton.InvokeMember(“单击”)
不起作用。显然,该页面不是通过
onclick
事件来处理这种点击。最可能的情况是,它使用
onmousedown
onmousedup
事件。研究页面的脚本逻辑以验证是否存在这种情况,请使用F12调试器并放置一些断点

已更新,如果页面确实使用了
onmousedown
/
onmousedup
,则您需要使您的
WebBrowser
可见,并通过发布
WM_LBUTTONDOWN
来实现自动化:

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication_22979038
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            this.webBrowser.DocumentText = "<a id='goLink' href='javascript:alert(\"Hello!\"),undefined'>Go</a><script></script>";

            this.webBrowser.DocumentCompleted += webBrowser_DocumentCompleted;
        }

        void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            var element = this.webBrowser.Document.GetElementById("goLink");
            element.Focus();
            var hwnd = GetFocus();
            if (!IsChild(this.webBrowser.Handle, hwnd))
                throw new ApplicationException("Unexpected focused window.");

            var rect = GetElementRect(element);
            IntPtr wParam = (IntPtr)MK_LBUTTON;
            IntPtr lParam = (IntPtr)(rect.Left | rect.Top << 16);
            PostMessage(hwnd, WM_LBUTTONDOWN, wParam, lParam);
            PostMessage(hwnd, WM_LBUTTONUP, wParam, lParam);
        }

        // get the element rect in window client area coordinates
        static Rectangle GetElementRect(HtmlElement element)
        {
            var rect = element.OffsetRectangle;
            int left = 0, top = 0;
            var parent = element;
            while (true)
            {
                parent = parent.OffsetParent;
                if (parent == null)
                    return new Rectangle(rect.X + left, rect.Y + top, rect.Width, rect.Height);
                var parentRect = parent.OffsetRectangle;
                left += parentRect.Left;
                top += parentRect.Top;
            }
        }

        // interop

        const int MK_LBUTTON = 0x0001;
        const int WM_LBUTTONDOWN = 0x0201;
        const int WM_LBUTTONUP = 0x0202;

        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int x;
            public int y;
        }

        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        static extern int PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

        [DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
        static extern IntPtr GetFocus();

        [DllImport("User32.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
        static extern bool IsChild(IntPtr hWndParent, IntPtr hWnd);
    }
}
使用系统;
使用系统图;
使用System.Runtime.InteropServices;
使用System.Windows.Forms;
命名空间WindowsFormsApplication_22979038
{
公共部分类主窗体:窗体
{
公共表格(
{
初始化组件();
}
私有void主窗体加载(对象发送方、事件参数e)
{
this.webBrowser.DocumentText=“”;
this.webBrowser.DocumentCompleted+=webBrowser_DocumentCompleted;
}
作废webBrowser_DocumentCompleted(对象发送者,WebBrowserDocumentCompletedEventArgs e)
{
var元素=this.webBrowser.Document.GetElementById(“goLink”);
元素Focus();
var hwnd=GetFocus();
如果(!IsChild(this.webBrowser.Handle,hwnd))
抛出新的ApplicationException(“意外的聚焦窗口”);
var rect=GetElementRect(元素);
IntPtr wParam=(IntPtr)MK_LBUTTON;

IntPtr lParam=(IntPtr)(rect.Left | rect.Top)对于接近的投票者,如果这是离题的,我想知道世界上会出现什么主题。抱歉…有一秒钟分心了…请提供用于查找元素的代码-以及实际查找的元素。请注意,并非所有内容都是“可单击的”…否则就不可能提出任何建议。当您显示浏览器时,代码也可以工作吗?@AlexeiLevenkov:谢谢。请查看我的编辑。“A”应该会收到单击…如果您通过
InvokeScript
将自己的单击处理程序添加到该元素,它会被调用吗?您是否尝试过
InvokeScript
之类的内容$(“#InvokeScript”).trigger(“click”)
(假设您在页面上已经有了jQuery)?我相信,根据您如何创建”WebBrowser控件,它是不可见的“它可能不会触发所有加载事件或合理布局控件,从而使元素隐藏-检查文档的大小/状态…如果您想要无头浏览器,您可能需要使用PhantomJS。@Noseratio:哇,这很有趣。它不起作用!但手动单击该项确实可以完美地工作。这里发生了什么?