WebBrowser导航功能不起作用,并且不调用处理程序

时间:2013-08-25 11:44:08

标签: c# asp.net webbrowser-control

以下代码。

我试图导航到一个网站并阅读信息,问题是Navigate不起作用,唯一被调用的事件是导航并且打印的Url为空,其他事件从未被调用。 我错过了什么?我必须使用Form类才能导航?我不能从控制台应用程序以编程方式使用它吗?

请帮忙。

class WebNavigator
{
    private readonly WebBrowser webBrowser;

    public WebNavigator()
    {
        webBrowser = new WebBrowser
        {
            AllowNavigation = true
        };

        webBrowser.Navigated += webBrowser_Navigated;
        webBrowser.Navigating += webBrowser_Navigating;
        webBrowser.DocumentCompleted += webBrowser_DocumentCompleted;
    }

    // Navigates to the given URL if it is valid. 
    public void Navigate(string address)
    {
        if (String.IsNullOrEmpty(address)) return;
        if (address.Equals("about:blank")) return;
        if (!address.StartsWith("http://") &&
            !address.StartsWith("https://"))
        {
            address = "http://" + address;
        }
        try
        {
            Trace.TraceInformation("Navigate to {0}", address);
            webBrowser.Navigate(new Uri(address));
        }
        catch (System.UriFormatException)
        {
            Trace.TraceError("Error");
            return;
        }
    }

    // Occurs when the WebBrowser control has navigated to a new document and has begun loading it.
    private void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
    {
        Trace.TraceInformation("Navigated to {0}", webBrowser.Url);
    }

    // Occurs before the WebBrowser control navigates to a new document.
    private void webBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
    {
        Trace.TraceInformation("Navigating to {0}", webBrowser.Url);
    }

    private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        var wb = sender as WebBrowser;
        Trace.TraceInformation("DocumentCompleted {0}", wb.Url);
    }
}

3 个答案:

答案 0 :(得分:6)

我会使用await/async

用法:

static async void  DoWork()
{
    var html = await GetHtmlAsync("http://www.google.com/");
}

实用方法

static Task<string> GetHtmlAsync(string url)
{
    var tcs = new TaskCompletionSource<string>();

    var thread = new Thread(() =>
    {
        WebBrowser wb = new WebBrowser();

        WebBrowserDocumentCompletedEventHandler documentCompleted = null;
        documentCompleted = async (o, s) =>
        {
            wb.DocumentCompleted -= documentCompleted;
            await Task.Delay(2000); //Run JS a few seconds more

            tcs.TrySetResult(wb.DocumentText);
            wb.Dispose();
            Application.ExitThread();
        };

        wb.ScriptErrorsSuppressed = true;
        wb.DocumentCompleted += documentCompleted;
        wb.Navigate(url);
        Application.Run();
    });

    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();

    return tcs.Task;
}

答案 1 :(得分:1)

您提到这是一个控制台应用。要使WebBrowser在控制台应用程序中工作,您需要确保浏览器的线程是STA线程(thread.SetApartmentState(ApartmentState.STA)。此外,为了能够处理事件,线程必须泵送消息(Application.Run)。考虑到这一点,您可能希望创建一个单独的线程(从主控制台线程)来运行WebBrowser。

答案 2 :(得分:1)

感谢您的回答。 通过添加包含Application.DoEvents();

的while子句解决了这个问题
            webBrowser.Navigate(new Uri(address));
            while (!navigationCompleted)
            {
                Application.DoEvents();
                Thread.Sleep(navigationPollInterval);
            }

我不确定这是否是最佳解决方案,我将很高兴听到更好的解决方案。