Использование WebBrowser в консольном приложении

Я хочу использовать его для вызова некоторых сценариев JS на веб-странице. У меня есть это:

    static void Stuff()
    {
        WebBrowser browser = new WebBrowser();
        browser.Navigate("http://www.iana.org/domains/example/");
        HtmlDocument doc = browser.Document;
        //doc.InvokeScript("someScript");
        Console.WriteLine(doc.ToString());
    }

    static void Main(string[] args)
    {
        Console.WriteLine("hi");
        var t = new Thread(Stuff);
        t.SetApartmentState(ApartmentState.STA);
        t.Start();
    }

Вопрос 1: я получаю исключение «ссылка на объект не установлена» при попытке получить doc.ToString(). Почему?

Вопрос 2: Как мне передать данные из HTML-документа в основную программу? WebBrowser требует отдельного потока, который требует статического метода, который не может возвращать никакого значения. Как мне вернуть, скажем, doc в Main(), чтобы я мог что-то с ним сделать?


person Hui    schedule 12.06.2011    source источник
comment
Статические методы действительно могут возвращать значение. Это потоки, которые не могут. Кроме того, потоки могут использовать нестатический метод.   -  person icktoofay    schedule 13.06.2011


Ответы (1)


Правильная идея, неправильное исполнение. WebBrowser.Navigate () только сообщает веб-браузеру о необходимости начать переход к запрашиваемой веб-странице. На это требуется время, обычно сотни миллисекунд. Internet Explorer внутренне запускает потоки для выполнения работы. Он сообщает вам, когда это будет сделано, путем вызова события DocumentCompleted. Вы не ждете этого, так что сначала это город крушения.

Следующая проблема заключается в том, что событие DocumentCompleted не будет вызвано в вашем коде. Вы должны соблюдать контракт STA, он требует от вас прокачки цикла сообщений. Это всесильный способ, которым фоновый поток, подобный тому, который IE использует для получения веб-страницы, сообщает вашему потоку о том, что задание выполнено.

Необходимый шаблонный код доступен в этом ответе .

person Hans Passant    schedule 12.06.2011
comment
Как бы вы построили цепочку действий? Вы хотите перейти на какую-либо страницу, затем ввести текст в текстовое поле и нажать «Поиск» или перейти. Вам нужно просто сделать объект WebBrowser глобальным, а затем связать вместе 4 метода, выполнить навигацию, выполнить навигацию по документу, ввести текст и нажать go, entertext и событие завершения документа hitgo? - person NathanTempelman; 21.03.2013
comment
Конечный автомат - это простое решение проблем асинхронного программирования. Просто отслеживайте состояние с помощью целого числа или перечисления. - person Hans Passant; 21.03.2013
comment
Небольшое примечание: при попытке автоматизировать элемент управления WebBrowser без взаимодействия с пользователем вы столкнетесь с серьезными проблемами со всплывающими диалогами, если вы не установите webBrowser.ScriptErrorsSuppressed = true (который, несмотря на свое название, подавляет все диалоги, а не только ошибки скрипта ). См. также. - person BlueRaja - Danny Pflughoeft; 16.12.2013