【问题标题】:WebBrowser doesn't get to DocumentCompleted eventWebBrowser 没有到达 DocumentCompleted 事件
【发布时间】:2012-05-30 01:06:33
【问题描述】:

我是 C# 的新手,我正在尝试构建一个登录网站并返回其源代码的程序。问题是,我在页面加载时注册了一个事件监听器,但是当我调试它时,它在设置相同的事件后退出,实际上并没有在页面“加载”后做我想要它做的事情。

这是源代码-

using System;
using System.Windows.Forms;

namespace WIN
{
    class Program
    {
        string url = -snip-;
        string username = -snip-;
        string password = -snip-;
        string task = -snip-;
        string action = -snip-;
        string timezone = -snip-;

        private void Login()
        {
            Console.WriteLine("Started.");
            Console.ReadLine();
            Console.WriteLine("Declaring WebBrowser instance browser...");
            WebBrowser browser = new WebBrowser();
            Console.WriteLine("Done.");
            Console.ReadLine();
            Console.WriteLine("Registering an event for when the page finishes loading...");
            browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(pageLoaded);
            Console.WriteLine("Done.");
            Console.ReadLine();
            Console.WriteLine("Using method Navigate of browser instance with url parameter...");
            browser.Navigate(url);
            Console.WriteLine("Done.");
            Console.ReadLine();

        }

        private void pageLoaded(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            Console.WriteLine("Declaring WebBrowser instance browser as sender...");
            WebBrowser browser = sender as WebBrowser;
            Console.WriteLine("Done.");
            Console.ReadLine();
            string response = browser.DocumentText;

            Console.WriteLine("Searching for authenticity token...");
            // looks in the page source to find the authenticity token.
            // could also use regular expressions here.
            int index = response.IndexOf("authenticity_token");
            int startIndex = index + 41;
            string authenticityToken = response.Substring(startIndex, 40);
            Console.WriteLine("Found authenticity token.");

            Console.WriteLine("Unregistering first event handler...");
            // unregisters the first event handler
            // adds a second event handler
            browser.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(pageLoaded);
            Console.WriteLine("Done.");
            Console.WriteLine("Adding second event handler...");
            browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(pageLoaded2);
            Console.WriteLine("Done.");
            Console.Read();

            Console.WriteLine("Formatting data to be posted to server...");
            string postData = string.Format("_user={0}&_pass={1}&authenticity_token={2}&_task{3}&_action{4}&_timezone{5}", username, password, authenticityToken, task, action, timezone);
            Console.WriteLine("Done.");
            Console.Read();

            Console.WriteLine("Declaring ASCIIEncoding instance enc...");
            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
            Console.WriteLine("Done.");
            Console.Read();

            //  we are encoding the postData to a byte array
            Console.WriteLine("Encoding postData to a byte array...");
            browser.Navigate(url, "", enc.GetBytes(postData), "Content-Type: application/x-www-form-urlencoded\r\n");
            Console.WriteLine("Done..");
            Console.Read();

        }

        [STAThread]
        static void Main(string[] args)
        {
            Program p = new Program();
            p.Login();
        }
    }
}

从所有这些控制台输出中,它只能到达 使用带有 url 参数的浏览器实例的方法 Navigate...

【问题讨论】:

  • 我从未见过在实际 Winforms 表单之外使用 WebBrowser 控件。

标签: c# browser


【解决方案1】:

WebBrowser 要求您的程序泵送一个消息循环。否则它不会触发它的事件。这通常是任何使用单线程 COM 组件的程序的要求。或者用更容易理解的术语来说:你不能让程序忙于从控制台读取数据,同时触发像 DocumentCompleted 这样的事件。一个线程一次只能做一件事。您可以通过编写一个 Winforms 应用程序或自己使用 Application.Run() 启动一个消息循环。使用消息循环,线程可以一次做不止一件事。但这确实需要与您现在编写的非常不同的代码,您仍然不能使用 Console.ReadLine(),而是使用 TextBox。

您可以通过在单独的线程中运行浏览器来挽救您拥有的东西,您可以在 this answer 中找到所需的代码。

【讨论】:

  • 我只是在使用 Console.Read();用于调试目的。如果我删除它们,程序会运行吗?
  • 另外,我认为 [STAThread] 解决了这个问题。无论如何,我不是 c# 的专业人士,但我会尝试使用您链接到的答案中的代码。
  • 当您删除 Console.Read 调用时,您的程序将立即终止,因为没有什么可以阻止它在代码中运行。您需要认真考虑切换到 Winforms 或 WPF 应用程序,控制台模式应用程序只会给您带来太多麻烦。对于简单的应用程序来说没问题,但在您的程序中运行浏览器并不是那么简单。
  • 看,我完全是 c# 的菜鸟。您介意解释一下什么是 Winforms 应用程序或 WPF 吗?我不需要,不,我不想要视觉组件。
猜你喜欢
  • 1970-01-01
  • 2015-09-02
  • 1970-01-01
  • 2012-09-05
  • 1970-01-01
  • 1970-01-01
  • 2014-01-01
  • 2011-08-20
  • 2017-06-08
相关资源
最近更新 更多