views:

120

answers:

4
+1  Q: 

WebBrowser control

Ok, so here's the deal -- I'm running a Windows Forms WebBrowser control from a service. I know thats a no-no, but it seems to work alright.

The only thing I'm running into a problem with is trying to wait for the browser's pages to load. In a normal application, I'd just do something like

while (browser.readystate != complete) Application.DoEvents()

Obviously this won't work from a service.

I've tried this as an alternative:

public class WebCrawler
{
    private class ExposedActiveXWebBrowser : System.Windows.Forms.WebBrowser
    {
        public SHDocVw.WebBrowser UnderlyingWebBrowser
        {
            get
            {
                return ActiveXInstance as SHDocVw.WebBrowser;
            }
        }
    }
    ExposedActiveXWebBrowser worker;

    public WebBrowserReadyState ReadyState
    {
        get
        {
            return worker.ReadyState;
        }
    }

    public HtmlDocument Document
    {
        get
        {
           return worker.Document;
        }
    }

    public WebCrawler()
    {
        worker = new ExposedActiveXWebBrowser();
    }

    public void Navigate(string urlString)
    {
        worker.Navigate(urlString);
        while (worker.UnderlyingWebBrowser.ReadyState != tagREADYSTATE.READYSTATE_COMPLETE)
            Thread.Sleep(0);
    }
}

That Navigate method, however, doesn't work. The ReadyState never changes from LOADING.

What I'm wondering is this -- Windows forms WebBrowsers seem to be inherently asynchronous, so does that mean the ActiveX control is already executing on its own thread? Can I, by accessing the underlying activex control through an appropriate interface, just wait for it to complete?

+1  A: 

As your class is called WebCrawler, can I assume that this service requests HTML an does something with it?

If that is the case then there are better classes to use to do this and you won't have this issue.

Such as System.Net.WebClient and System.Net.HttpWebRequest

Chris Diver
Yeah, I've used those. The problem I've run into is figuring out a lot of the authentication hoops I've got to jump through to get to certain pages.
Joshua Evensen
@Joshua, what authentication problems are you having? Maybe they'd make for a good followup question.
Tim Robinson
Thats a possibility and thats how I'd like to eventually handle this problem, but can anyone answer my question just to satisfy my curiousity?Does the ActiveX control get its own thread? Is there a reason the readystate isn't changing?
Joshua Evensen
A: 

+1 for Chris -- If you can't see the WebControl why would you want to render it? Use something like the HTMLAgilityPack to parse a DOM model for the page if needed.

csharptest.net
+1  A: 

You could try the DocumentCompleted event.

From MSDN:

Occurs when the WebBrowser control finishes loading a document.

...

Handle the DocumentCompleted event to receive notification when the new document finishes loading. When the DocumentCompleted event occurs, the new document is fully loaded, which means you can access its contents through the Document, DocumentText, or DocumentStream property.

fletcher
That event won't fire. That's the problem.
Hans Passant
A: 

Solution: I needed to run the service as a user with full trust. it's explicitly required via the PermissionSet attribute.

Joshua Evensen