2

好的,这就是交易 - 我正在WebBrowser从服务运行 Windows 窗体控件。我知道这是一个禁忌,但它似乎工作正常。

我遇到的唯一问题是尝试等待浏览器的页面加载。在正常的应用程序中,我会做类似的事情

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

显然,这不适用于服务。

我试过这个作为替代方案:

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

但是,该 Navigate 方法不起作用。ReadyState 永远不会从 LOADING 改变。

我想知道的是——Windows 窗体 WebBrowsers 似乎本质上是异步的,这是否意味着 ActiveX 控件已经在其自己的线程上执行?

我可以通过适当的接口访问底层的activex控件,等待它完成吗?

4

4 回答 4

2

您可以尝试DocumentCompleted事件。

来自 MSDN:

在 WebBrowser 控件完成加载文档时发生。

...

处理 DocumentCompleted 事件以在新文档完成加载时接收通知。当 DocumentCompleted 事件发生时,新文档已完全加载,这意味着您可以通过 Document、DocumentText 或 DocumentStream 属性访问其内容。

于 2010-07-26T17:33:25.697 回答
2

解决方案:我需要以完全信任的用户身份运行该服务。它是通过 PermissionSet 属性明确要求的。

于 2010-08-03T22:20:18.440 回答
1

由于您的课程称为 WebCrawler,我可以假设该服务请求 HTML 并对其进行处理吗?

如果是这种情况,那么可以使用更好的类来执行此操作,并且您不会遇到此问题。

比如System.Net.WebClientSystem.Net.HttpWebRequest

于 2010-07-26T17:12:17.183 回答
0

为 Chris +1 - 如果您看不到 WebControl,为什么要渲染它?如果需要,使用HTMLAgilityPack之类的东西来解析页面的 DOM 模型。

于 2010-07-26T17:18:39.620 回答