C#WebBrowser控件中的编程按钮单击

C#WebBrowser控件中的编程按钮单击,c#,winforms,C#,Winforms,WinForms中webbrowser的文档指定您可以调用以下事件: webBrowser1.Document.GetElementById("signin").InvokeMember("click"); …但这对我不起作用。我尝试了一个黑客: HtmlElement element = webBrowser1.Document.CreateElement("script"); element.InnerText = "f

WinForms中webbrowser的文档指定您可以调用以下事件:

webBrowser1.Document.GetElementById("signin").InvokeMember("click");
…但这对我不起作用。我尝试了一个黑客:

HtmlElement element = webBrowser1.Document.CreateElement("script");
element.InnerText = "function SubmitForm() { document.getElementById('signin').click(); }";
webBrowser1.Document.Forms[0].AppendChild(element);
webBrowser1.Document.InvokeScript("SubmitForm");
…这也没用。然而,另一个黑客:

HtmlElement element = webBrowser1.Document.CreateElement("script");
element.InnerText = "function SubmitForm() { alert('Click me!'); 
    document.getElementById('signin').click(); }";
webBrowser1.Document.Forms[0].AppendChild(element);
webBrowser1.Document.InvokeScript("SubmitForm");
…工作得很好。除了有用户干预,点击警报框,这是我不想要的。这是某种比赛条件吗?代码在webBrowser1\u DocumentCompleted中执行,因此应该没有问题。如果你有办法成功触发事件,请告诉我

@Jimi这是您请求的代码:

private void Form1_Load(object sender, EventArgs e)
{
    string targetUrl = "https://banking.westpac.com.au/wbc/banking/handler?TAM_OP=login&URL=%2Fsecure%2Fbanking%2Foverview%2Fdashboard";
    webBrowser1.Navigate(targetUrl);
}

private void webBrowser1_DocumentCompleted_1(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    webBrowser1.DocumentCompleted -= webBrowser1_DocumentCompleted_1;
    webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted_2;

    webBrowser1.Document.GetElementById("fakeusername").InnerText = "andy";
    webBrowser1.Document.GetElementById("password").InnerText = "password";
    //webBrowser1.Document.GetElementById("signin").InvokeMember("click");

    HtmlElement element = webBrowser1.Document.CreateElement("script");
    element.InnerText = "function SubmitForm() { setTimeout(function() { document.getElementById('signin').click(); }, 5000); }";
    webBrowser1.Document.Forms[0].AppendChild(element);
    webBrowser1.Document.InvokeScript("SubmitForm");
}

警报使其工作(setTimeout也工作)。看起来文档并没有真正完成,但浏览器认为它已经完成了。页面上的JS能做到这一点吗?

根据您的解决方法,我猜这可能是由于您试图执行代码时文档尚未加载所致。为了确保页面已加载,您可以订阅
DocumentCompleted
事件并在那里执行您的操作。这对我很有用:

public Form1()
{
    InitializeComponent();

    webBrowser1.DocumentCompleted += WebBrowser1_DocumentCompleted;
    string curDir = Directory.GetCurrentDirectory();
    webBrowser1.Navigate($"file://{curDir}/test.html");
}

private void WebBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    webBrowser1.Document.GetElementById("btn").InvokeMember("onclick");
}
我看到的另一个问题是,您正在使用
单击
成员,因为我不确定元素是什么(可能是
按钮
?),然后尝试调用
onclick
,就像我在提供的代码中所做的那样

这样的片段对我也很有用:

public Form1()
{
    InitializeComponent();

    webBrowser1.DocumentCompleted += WebBrowser1_DocumentCompleted;
    webBrowser1.Navigate(@"https://banking.westpac.com.au/wbc/banking/handler?TAM_OP=login&URL=%2Fsecure%2Fbanking%2Foverview%2Fdashboard");
}

private void WebBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    webBrowser1.Document.GetElementById("signin").InvokeMember("click");
}

我的理论被证明是正确的,我终于找到了答案:

完成的事件似乎并不等待所有脚本停止执行


感谢大家的贡献。

您能在
文档完成处理程序中发布您的代码吗?
DocumentCompleted
事件可以引发(几乎总是)多次。。。为什么在那里有
警报(…)
?没有它不工作吗?顺便说一句,请阅读事件处理程序中的注释,您显然不是在等待文档完成。请参阅我链接的帖子中的代码。-取消订阅并订阅另一个处理程序真的没有用。此外,除非您在其他地方删除该订阅,
webBrowser1\u DocumentCompleted\u 2
将被多次调用,并且其用法不清楚;反正也帮不上忙。你没有读我链接的帖子中的注释。该事件(大多数情况下)可以多次引发,因为它是针对主文档页面中的每个子文档引发的。对于文档中的每个帧/IFrame,可以将其提升一次或多次。这就是为什么总是有这样的检查:
if([WebBrowser].ReadyState!=WebBrowserReadyState.Complete)return在该处理程序中。-如果您需要处理不同的文档源,请使用可以区分当前正在读取的页面的方法。无法添加数百个事件处理程序来处理数百个不同的页面。1。文件明确地说:。这里没有对JavaScript操作的引用,这也会导致事件多次引发,这就是
ReadyState
属性的作用。这不是秘密,这是所有网络浏览器的标准文件。2.我看不出当你处理默认行为时有什么反模式。当文档完成时,您需要一种基于当前URL解析网页的方法。这不是设计,而是WebBrowser(所有WebBrowser)的工作方式。你不需要任何循环。每次引发事件时,只需检查
ReadyState
,并跟踪
Complete
状态所指的HtmlDocument或子文档。--你有这种行为,不管你处理什么样的网络浏览器,这就是它们的工作原理。HTML页面是动态的,它们可以在不同的阶段生成,服务器可能会发送部分文档,然后根据结构和数据源填充并部分或全部重新发送,JavaScript可以做同样的客户端等。谢谢,但我已经使用webBrowser1_DocumentCompleted和'onclick'不起作用了。@Andy你能分享JS和HTML吗?它是某个网站还是本地文件?完整的HTML可以在目标URL上找到:@Andy Similair代码也适用于我,请参阅编辑。谢谢,我尝试了相同的代码,但仍然出现错误。唯一的区别是我将ScriptErrorsSuppressed设置为true。如果我把它设为false,它会工作,但可能是由于交互式弹出窗口。我将VS2013用于这个项目(长话短说)。所以,也许这是一个从那时起就被修复的bug….?顺便说一句,我并不提倡紧循环。。100毫秒的等待可能更好。
webBrowser1.Navigate(@"somesite.com");
while (WebBrowser1.ReadyState != WebBrowserReadyState.Complete)
{
    txtLoad.Text = WebBrowser1.ReadyState.ToString();
    Application.DoEvents();
    System.Threading.Thread.Sleep(1);
}
webBrowser1.Document.GetElementById("gwt-uid-126").InvokeMember("click");