سؤال

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?

هل كانت مفيدة؟

المحلول 2

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

نصائح أخرى

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.

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

+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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top