简体   繁体   English

WebBrowser控件无法响应InvokeMember(“click”)

[英]WebBrowser control not responding to InvokeMember(“click”)

After spending 5 days of my life, I'm about to give up on this, but am consulting the experts once before that. 在我度过了5天的生活之后,我即将放弃这一点,但在此之前我会咨询专家。

I have a WebBrowser control that loads a webpage and I programmatically scrape its contents. 我有一个WebBrowser控件加载网页,我以编程方式抓取其内容。 Clicking a particular menu item in the page brings up File Open dialog when done in IE (or any other browser). 在IE(或任何其他浏览器)中完成后,单击页面中的特定菜单项将显示“文件打开”对话框。 But clicking the same button in WebBrowser control using InvokeMember() apparently doesn't do anything no matter what. 但是使用InvokeMember()在WebBrowser控件中单击相同的按钮显然无论如何都不会执行任何操作。 I've gone through several SO questions such as Setting Browser Features to make sure my control behaves exactly like IE, but that hasn't succeeded. 我已经经历了几个SO问题,比如设置浏览器功能 ,以确保我的控件行为与IE完全一样,但是没有成功。

I went as far as inspecting the actual javascript function that the button is executing behind the scene and calling it manually using HtmlDocument.InvokeScript() but couldn't do that because the underlying function takes an argument of MouseEvent type (the click event actually) and I'm not sure how can I create that object in C#. 我一直在检查按钮在场景后面执行的实际javascript函数,并使用HtmlDocument.InvokeScript()手动调用它,但是由于底层函数采用了MouseEvent类型的参数(实际上是click事件),所以不能这样做而且我不确定如何在C#中创建该对象。

Another approach was to set focus to that particular button and then try SendKeys , but that won't work because the WebBrowser control is not visible. 另一种方法是将焦点设置为该特定按钮,然后尝试SendKeys ,但这不起作用,因为WebBrowser控件不可见。 It is just an in-memory instance. 它只是一个内存实例。 To be more specific, the WebBrowser 更具体地说,WebBrowser

EDIT 编辑

On a reader's request, here's the simple code that I'm using to find the element: 根据读者的要求,这是我用来查找元素的简单代码:

var MyButton = WB.Document.GetElementById("processfilelink");

processfilelink is an anchor tag ( <a href='#' ... > ) and I have confirmed that this element actually exists in the body of the document. processfilelink是一个锚标记( <a href='#' ... > processfilelink ),我已经确认该元素实际存在于文档正文中。 The webpage uses jQuery's delegate feature to bind this anchor's click event to the target function. 该网页使用jQuery的delegate功能将此锚click事件绑定到目标函数。 After locating the button, I simply call InvokeMember() like this: 找到按钮后,我只需调用这样的InvokeMember()

MyButton.InvokeMember("click");

Note: I also see bindings for mousedown, mouseup and focus events in the page code. 注意:我还在页面代码中看到mousedown,mouseup和focus事件的绑定。 I expect all these events to automatically fire when one invokes click , but just to be sure I added InvokeMember calls for these events too. 我希望所有这些事件在调用click时自动触发,但是为了确保我InvokeMember为这些事件添加了InvokeMember调用。 Results are no better. 结果并不好。

From the comments: 来自评论:

... load this page in full IE browser, use F12 Tools to debug it and execute button.click() in JavaScript console. ...在完整的IE浏览器中加载此页面,使用F12工具对其进行调试并在JavaScript控制台中执行button.click()。 Does it work as expected this way? 它是否按预期工作?

So, you've tried that, and the result is: 所以,你已经尝试过,结果是:

... now that's interesting. ......现在这很有趣。 It doesn't work! 它不起作用! But clicking on the item by hand does work flawlessly. 但是手动点击该项目确实可以正常工作。 What's going on here? 这里发生了什么?

I suspected that as MyButton.InvokeMember("click") doesn't work. 我怀疑,因为MyButton.InvokeMember("click")不起作用。 Apparently, the page handles this click by other means than via onclick event. 显然,页面通过其他方式处理此单击,而不是通过onclick事件。 Most likely, it uses onmousedown or onmouseup events. 最有可能的是,它使用onmousedownonmouseup事件。 Study the page's scripting logic to verify if that's the case, use F12 debugger and put some break points. 研究页面的脚本逻辑来验证是否是这种情况,使用F12调试器并设置一些断点。

Updated , if it turns out the page indeed uses onmousedown / onmouseup , you'd need to make your WebBrowser visible and automate it by posting WM_LBUTTONDOWN : 更新后 ,如果事实证明页面确实使用onmousedown / onmouseup ,则需要通过发布WM_LBUTTONDOWN使WebBrowser可见并自动化它:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 WebBrowser控件中的InvokeMember(“单击”) - InvokeMember(“click”) in WebBrowser control InvokeMember(“click”) webBrowser 帮助 - InvokeMember(“click”) webBrowser help InvokeMember(“ click”)在线程内的webBrowser控件中不起作用 - InvokeMember(“click”) doesn't work in webBrowser control inside a thread C# WebBrowser 控件 - 使用 InvokeMember("Click") 提交表单不工作 - C# WebBrowser Control - Form Submit Not Working using InvokeMember("Click") GeckoFX - WebBrowser控件的“RaiseEvent”或“InvokeMember”的替代品 - GeckoFX - alternative of WebBrowser control's “RaiseEvent” or “InvokeMember” btn.InvokeMember(“ click”)或btn.RaiseEvents(“ click”),其他任何情况都不会在Webbrowser上单击“确定” btn - btn.InvokeMember(“click”), or btn.RaiseEvents(“click”), and anything else won't click an 'OK' btn on webbrowser InvokeMember(“ Click”)Web浏览器控件错误C#WPF - InvokeMember(“Click”) Web Browser control error C# WPF C# Webbrowser 文档,invokemember(“click”),是否可以等到单击操作解决? - C# Webbrowser document , invokemember(“click”), is it possible to wait until that click action is resolved? InvokeMember不适用于WPF Webbrowser - InvokeMember does not work with WPF Webbrowser C#WebBrowser HTMLElement.InvokeMember(“click”)无效 <form> 标签 - C# WebBrowser HTMLElement.InvokeMember(“click”) not working within <form> tag
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM