WebBrowser Navigating function doesn’t work and handlers are not called

Code below.

I am trying to navigate to a website and read information, the problem is that Navigate doesn’t work, the only event that is called is Navigating and the printed Url is empty, the other events are never called.
what am I missing? do I have to use Form class in order to navigate? can’t I use it programatically from a Console application?

Please help.

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

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I would make use of await/async.

Usage:

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

The utility method

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

Method 2

You mentioned this is a console app. For WebBrowser to work in a console app, you need to make sure the browser’s thread is an STA thread (thread.SetApartmentState(ApartmentState.STA). Also, to be able to handle events, the thread must pump messages (Application.Run). Considering this, you may want to create a separate thread (from your main console thread) to run WebBrowser.

Method 3

Thanks for the answers.
The problem was solved by adding this while clause including Application.DoEvents();

            webBrowser.Navigate(new Uri(address));
            while (!navigationCompleted)
            {
                Application.DoEvents();
                Thread.Sleep(navigationPollInterval);
            }

I am not sure if this is the best solution, I would be grateful to hear better solutions.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x