2

I'm working on a application that hosts WebBrowser control and saves web page screenshots. (C#, VS2008, IE 9, Vista. all up to date. FEATURE_BROWSER_EMULATION is set to 0x2328)

The application takes a list of urls and navigates to the urls one by one and saves screenshots. Application flow is simply as follows : Read url from file, fetch it using HttpWebRequest first, if it exists and if it's html call webBrowser.Navigate(url), wait until WebBrowser.ReadyState is WebBrowserReadyState.Complete (handle WebBrowser.DocumentCompleted events and simply do nothing until ReadyState is WebBrowserReadyState.Complete), wait for a few seconds more just to be safe(tested up to 10 secs), save screenshot and move to next url. It works properly for almost all urls (pages from many different sites) but the WebBrowser embedded in my application does not render some urls, especially pages from www.securityfocus.com for example : http://www.securityfocus.com/bid/52023

I tried disabling cache, clearing the cache before every request, wait for up to 10 seconds just to give it some time to render etc to no avail. I visually confirmed that the WebBrowser does not render the page, it's not a problem related to saving the screenshot(I'm using BitBlt but I don't think it's relevant). The page renders normally using IE.

Please let me know if you have any recommendations as to why this is happening. Thanks in advance

Serkan Özkan
  • 377
  • 2
  • 10

1 Answers1

3

I managed to solve this problem! It turned out that webbrowser needs a small amount of time to actually render the page after final DocumentCompleted event is fired. Normally we don't notice this slight delay but when you have a loop running right after the last(many DocumentCompleted events will be fired while loading a url) DocumentCompleted for the page, webbrowser can not find time to render the page before you save the screenshot.So you have to give it some time to render the page.

If you naively call sleep on the UI thread to wait for rendering, rendering will also sleep and the page will not be rendered before you save the screenshot.

So you have to wait in another thread, leave the UI thread idle to allow time to complete page rendering and then return to the UI thread from the child thread by calling Invoke method on the main UI thread.

Serkan Özkan
  • 377
  • 2
  • 10