Advertisement
Guest User

WebBrowserUtil

a guest
May 12th, 2015
451
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 32.08 KB | None | 0 0
  1. using mshtml;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Text;
  7. using System.Threading;
  8. using System.Threading.Tasks;
  9. using System.Windows.Threading;
  10.  
  11. namespace ConsoleApplication8
  12. {
  13.     class WebBrowserUtil
  14.     {
  15.         public static TimeSpan DefaultConfig_BrowserLoadTimeout = TimeSpan.FromSeconds(30);
  16.         public static TimeSpan DefaultConfig_BrowserRenderTime = TimeSpan.FromSeconds(5);
  17.         public static TimeSpan DefaultConfig_SyncContextPostCheckInterval = TimeSpan.FromMilliseconds(10);
  18.         public static TimeSpan DefaultConfig_ActiveXInstanceInitTime = TimeSpan.FromMilliseconds(200);
  19.  
  20.         public enum WebBrowserTypeEnum { Forms, Wpf }
  21.         public class WebBrowserContext : IDisposable
  22.         {
  23.             private Thread StaThread { get; set; }
  24.  
  25.             public WebBrowserTypeEnum WebBrowserType { get; private set; }
  26.             public SynchronizationContext SyncContext { get; set; }
  27.  
  28.             private object WebBrowser { get; set; }
  29.             public System.Windows.Forms.WebBrowser GetWebBrowserAsFormsType()
  30.             {
  31.                 EnsureWebBrowserType(WebBrowserTypeEnum.Forms);
  32.                 return WebBrowser as System.Windows.Forms.WebBrowser;
  33.             }
  34.             public System.Windows.Controls.WebBrowser GetWebBrowserAsWpfType()
  35.             {
  36.                 EnsureWebBrowserType(WebBrowserTypeEnum.Wpf);
  37.                 return WebBrowser as System.Windows.Controls.WebBrowser;
  38.             }
  39.  
  40.             public WebBrowserContext(WebBrowserTypeEnum browserType)
  41.             {
  42.                 WebBrowserType = browserType;
  43.                 switch (browserType)
  44.                 {
  45.                     case WebBrowserTypeEnum.Forms:
  46.                         {
  47.                             StaThread = new Thread(() =>
  48.                             {
  49.                                 SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher));
  50.                                 SyncContext = SynchronizationContext.Current;
  51.                                 System.Windows.Forms.Application.Run();
  52.                             });
  53.                             StaThread.SetApartmentState(ApartmentState.STA);
  54.                             StaThread.IsBackground = true;
  55.                             StaThread.Start();
  56.                             while (null == SyncContext) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  57.                             SyncContext.Post(state => { WebBrowser = new System.Windows.Forms.WebBrowser(); }, null);
  58.                             while (null == WebBrowser) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  59.                         }
  60.                         break;
  61.  
  62.                     case WebBrowserTypeEnum.Wpf:
  63.                         {
  64.                             StaThread = new Thread(() =>
  65.                             {
  66.                                 SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher));
  67.                                 SyncContext = SynchronizationContext.Current;
  68.                                 new System.Windows.Application().Run();
  69.                             });
  70.                             StaThread.SetApartmentState(ApartmentState.STA);
  71.                             StaThread.IsBackground = true;
  72.                             StaThread.Start();
  73.                             while (null == SyncContext) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  74.                             SyncContext.Post(state =>
  75.                             {
  76.                                 WebBrowser = new System.Windows.Controls.WebBrowser();
  77.                                 var window = new System.Windows.Window();
  78.                                 window.Content = WebBrowser;
  79.                                 window.Visibility = System.Windows.Visibility.Hidden;
  80.                                 window.Show();
  81.                             }, null);
  82.                             while (null == WebBrowser) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  83.                         }
  84.                         break;
  85.  
  86.                     default: throw new ArgumentException("unknown browser type", browserType.ToString());
  87.                 }
  88.             }
  89.  
  90.             private void EnsureWebBrowserType(WebBrowserTypeEnum browserType) { if (browserType != WebBrowserType) throw new ArgumentException(string.Format("web browser is of [{0}] type", WebBrowserType.ToString())); }
  91.  
  92.             public void Dispose()
  93.             {
  94.                 switch (WebBrowserType)
  95.                 {
  96.                     case WebBrowserTypeEnum.Forms:
  97.                         SyncContext.Post(state => System.Windows.Forms.Application.ExitThread(), null);
  98.                         break;
  99.  
  100.                     case WebBrowserTypeEnum.Wpf:
  101.                         SyncContext.Post(state => System.Windows.Application.Current.Shutdown(), null);
  102.                         break;
  103.  
  104.                     default: throw new ArgumentException("unknown browser type", WebBrowserType.ToString());
  105.                 }
  106.             }
  107.         }
  108.  
  109.         #region GetActiveXInstance
  110.         public static object GetActiveXInstance(WebBrowserContext browserContext)
  111.         {
  112.             object axi = null;
  113.             var finished = false;
  114.             switch (browserContext.WebBrowserType)
  115.             {
  116.                 case WebBrowserTypeEnum.Forms:
  117.                     {
  118.                         var browser = browserContext.GetWebBrowserAsFormsType();
  119.                         browserContext.SyncContext.Post(state =>
  120.                         {
  121.                             axi = GetActiveXInstance(browser);
  122.                             finished = true;
  123.                         }, null);
  124.                     }
  125.                     break;
  126.  
  127.                 case WebBrowserTypeEnum.Wpf:
  128.                     {
  129.                         var browser = browserContext.GetWebBrowserAsWpfType();
  130.                         browserContext.SyncContext.Post(state =>
  131.                         {
  132.                             axi = GetActiveXInstance(browser);
  133.                             finished = true;
  134.                         }, null);
  135.                     }
  136.                     break;
  137.  
  138.                 default: throw new ArgumentException("unknown browser type", browserContext.WebBrowserType.ToString());
  139.             }
  140.             while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  141.  
  142.             return axi;
  143.         }
  144.         public static object GetActiveXInstance(System.Windows.Forms.WebBrowser browser) { return browser.ActiveXInstance; }
  145.         public static object GetActiveXInstance(System.Windows.Controls.WebBrowser browser) { return GetActiveXInstance_ByProperty(browser); }
  146.         private static object GetActiveXInstance_ByProperty(System.Windows.Controls.WebBrowser browser)
  147.         {
  148.             var propertyName = "ActiveXInstance";
  149.             var axiPi = typeof(System.Windows.Controls.WebBrowser).GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic);
  150.             if (null == axiPi) throw new ArgumentException("failed to get property info of WebBrowser", propertyName);
  151.  
  152.             var axi = axiPi.GetValue(browser, null);
  153.             return axi;
  154.         }
  155.         private static object GetActiveXInstance_ByField(System.Windows.Controls.WebBrowser browser)
  156.         {
  157.             var fieldName = "_axIWebBrowser2";
  158.             var fiComWebBrowser = typeof(System.Windows.Controls.WebBrowser).GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
  159.             if (fiComWebBrowser == null) throw new ArgumentException("failed to get field info of WebBrowser", fieldName);
  160.  
  161.             var objComWebBrowser = fiComWebBrowser.GetValue(browser);
  162.             return objComWebBrowser;
  163.         }
  164.         #endregion
  165.  
  166.         #region GetDocumentHtml
  167.         public static string GetDocumentHtml(WebBrowserContext browserContext)
  168.         {
  169.             string docHtml = null;
  170.             var finished = false;
  171.             switch (browserContext.WebBrowserType)
  172.             {
  173.                 case WebBrowserTypeEnum.Forms:
  174.                     {
  175.                         var browser = browserContext.GetWebBrowserAsFormsType();
  176.                         browserContext.SyncContext.Post(state =>
  177.                         {
  178.                             docHtml = GetDocumentHtml(browser);
  179.                             finished = true;
  180.                         }, null);
  181.                     }
  182.                     break;
  183.  
  184.                 case WebBrowserTypeEnum.Wpf:
  185.                     {
  186.                         var browser = browserContext.GetWebBrowserAsWpfType();
  187.                         browserContext.SyncContext.Post(state =>
  188.                         {
  189.                             docHtml = GetDocumentHtml(browser);
  190.                             finished = true;
  191.                         }, null);
  192.                     }
  193.                     break;
  194.  
  195.                 default: throw new ArgumentException("unknown browser type", browserContext.WebBrowserType.ToString());
  196.             }
  197.             while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  198.  
  199.             return docHtml;
  200.         }
  201.         public static string GetDocumentHtml(System.Windows.Forms.WebBrowser browser)
  202.         {
  203.             var doc = (IHTMLDocument3)browser.Document.DomDocument;
  204.             return GetDocumentHtml(doc);
  205.         }
  206.         public static string GetDocumentHtml(System.Windows.Controls.WebBrowser browser)
  207.         {
  208.             var doc = (IHTMLDocument3)browser.Document;
  209.             return GetDocumentHtml(doc);
  210.         }
  211.         private static string GetDocumentHtml(IHTMLDocument3 document)
  212.         {
  213.             if (null == document) return null;
  214.             else if (null == document.documentElement) return null;
  215.             else return document.documentElement.outerHTML;
  216.         }
  217.         #endregion
  218.  
  219.         #region SuppressScriptErrors
  220.         public static void SuppressScriptErrors(WebBrowserContext browserContext, bool suppress)
  221.         {
  222.             ForceInitActiveXInstance(browserContext);
  223.  
  224.             var finished = false;
  225.             switch (browserContext.WebBrowserType)
  226.             {
  227.                 case WebBrowserTypeEnum.Forms:
  228.                     {
  229.                         var browser = browserContext.GetWebBrowserAsFormsType();
  230.                         browserContext.SyncContext.Post(state =>
  231.                         {
  232.                             SuppressScriptErrors(browser, suppress);
  233.                             finished = true;
  234.                         }, null);
  235.                     }
  236.                     break;
  237.  
  238.                 case WebBrowserTypeEnum.Wpf:
  239.                     {
  240.                         var browser = browserContext.GetWebBrowserAsWpfType();
  241.                         browserContext.SyncContext.Post(state =>
  242.                         {
  243.                             SuppressScriptErrors(browser, suppress);
  244.                             finished = true;
  245.                         }, null);
  246.                     }
  247.                     break;
  248.  
  249.                 default: throw new ArgumentException("unknown browser type", browserContext.WebBrowserType.ToString());
  250.             }
  251.             while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  252.         }
  253.         public static void SuppressScriptErrors(System.Windows.Forms.WebBrowser browser, bool suppress)
  254.         {
  255.             browser.ScriptErrorsSuppressed = suppress;
  256.         }
  257.         public static void SuppressScriptErrors(System.Windows.Controls.WebBrowser browser, bool suppress)
  258.         {
  259.             var objComWebBrowser = GetActiveXInstance(browser);
  260.             if (objComWebBrowser == null)
  261.             {
  262.                 browser.Loaded += (o, s) => SuppressScriptErrors(browser, suppress);        // in case we are too early
  263.                 return;
  264.             }
  265.             objComWebBrowser.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, objComWebBrowser, new object[] { suppress });
  266.         }
  267.         #endregion
  268.  
  269.         #region BlockNewWindows
  270.         public static void BlockNewWindows(WebBrowserContext browserContext, bool block)
  271.         {
  272.             ForceInitActiveXInstance(browserContext);
  273.  
  274.             var finished = false;
  275.             switch (browserContext.WebBrowserType)
  276.             {
  277.                 case WebBrowserTypeEnum.Forms:
  278.                     {
  279.                         var browser = browserContext.GetWebBrowserAsFormsType();
  280.                         browserContext.SyncContext.Post(state =>
  281.                         {
  282.                             BlockNewWindows(browser, block);
  283.                             finished = true;
  284.                         }, null);
  285.                     }
  286.                     break;
  287.  
  288.                 case WebBrowserTypeEnum.Wpf:
  289.                     {
  290.                         var browser = browserContext.GetWebBrowserAsWpfType();
  291.                         browserContext.SyncContext.Post(state =>
  292.                         {
  293.                             BlockNewWindows(browser, block);
  294.                             finished = true;
  295.                         }, null);
  296.                     }
  297.                     break;
  298.  
  299.                 default: throw new ArgumentException("unknown browser type", browserContext.WebBrowserType.ToString());
  300.             }
  301.             while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  302.         }
  303.  
  304.         public static void BlockNewWindows(System.Windows.Forms.WebBrowser browser, bool block)
  305.         {
  306.             if (block) browser.NewWindow += OnNewWindow;
  307.             else browser.NewWindow -= OnNewWindow;
  308.         }
  309.         private static void OnNewWindow(object sender, System.ComponentModel.CancelEventArgs e) { e.Cancel = true; }
  310.  
  311.         public static void BlockNewWindows(System.Windows.Controls.WebBrowser browser, bool block)
  312.         {
  313.             var axi = GetActiveXInstance(browser);
  314.             if (null == axi)
  315.             {
  316.                 browser.Loaded += (o, s) => BlockNewWindows(browser, block);        // in case we are too early
  317.                 return;
  318.             }
  319.  
  320.             var iwb = axi as SHDocVw.IWebBrowser2;
  321.             if (null == iwb) throw new ArgumentException("failed to cast WebBrowser to IWebBrowser2");
  322.  
  323.             var wbEvents = iwb as SHDocVw.DWebBrowserEvents_Event;
  324.             if (null == wbEvents) throw new ArgumentException("failed to cast IWebBrowser2 to DWebBrowserEvents_Event");
  325.  
  326.             var wbEvents2 = iwb as SHDocVw.DWebBrowserEvents2_Event;
  327.             if (null == wbEvents2) throw new ArgumentException("failed to cast IWebBrowser2 to DWebBrowserEvents2_Event");
  328.  
  329.             if (block)
  330.             {
  331.                 wbEvents.NewWindow += OnNewWindow;
  332.                 wbEvents2.NewWindow2 += OnNewWindow2;
  333.                 wbEvents2.NewWindow3 += OnNewWindow3;
  334.             }
  335.             else
  336.             {
  337.                 wbEvents.NewWindow -= OnNewWindow;
  338.                 wbEvents2.NewWindow2 -= OnNewWindow2;
  339.                 wbEvents2.NewWindow3 -= OnNewWindow3;
  340.             }
  341.         }
  342.         private static void OnNewWindow(string url, int flags, string targetFrameName, ref object postData, string headers, ref bool processed) { processed = true; }
  343.         private static void OnNewWindow2(ref object ppDisp, ref bool cancel) { cancel = true; }
  344.         private static void OnNewWindow3(ref object ppDisp, ref bool cancel, uint flags, string urlContext, string url) { cancel = true; }
  345.         #endregion
  346.  
  347.         #region DisableFileDownload
  348.         public static void DisableFileDownload(WebBrowserContext browserContext, bool disable)
  349.         {
  350.             ForceInitActiveXInstance(browserContext);
  351.  
  352.             var finished = false;
  353.             switch (browserContext.WebBrowserType)
  354.             {
  355.                 case WebBrowserTypeEnum.Forms:
  356.                     {
  357.                         var browser = browserContext.GetWebBrowserAsFormsType();
  358.                         browserContext.SyncContext.Post(state =>
  359.                         {
  360.                             DisableFileDownload(browser, disable);
  361.                             finished = true;
  362.                         }, null);
  363.                     }
  364.                     break;
  365.  
  366.                 case WebBrowserTypeEnum.Wpf:
  367.                     {
  368.                         var browser = browserContext.GetWebBrowserAsWpfType();
  369.                         browserContext.SyncContext.Post(state =>
  370.                         {
  371.                             DisableFileDownload(browser, disable);
  372.                             finished = true;
  373.                         }, null);
  374.                     }
  375.                     break;
  376.  
  377.                 default: throw new ArgumentException("unknown browser type", browserContext.WebBrowserType.ToString());
  378.             }
  379.             while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  380.         }
  381.         public static void DisableFileDownload(System.Windows.Forms.WebBrowser browser, bool disable)
  382.         {
  383.             var axi = GetActiveXInstance(browser);
  384.             DisableFileDownload(axi, disable);
  385.         }
  386.         public static void DisableFileDownload(System.Windows.Controls.WebBrowser browser, bool disable)
  387.         {
  388.             var axi = GetActiveXInstance_ByProperty(browser);
  389.             if (null == axi)
  390.             {
  391.                 browser.Loaded += (o, s) => DisableFileDownload(browser, disable);        // in case we are too early
  392.                 return;
  393.             }
  394.  
  395.             DisableFileDownload(axi, disable);
  396.         }
  397.         private static void DisableFileDownload(object activexInstance, bool disable)
  398.         {
  399.             var iwb = activexInstance as SHDocVw.IWebBrowser2;
  400.             if (null == iwb) throw new ArgumentException("failed to cast WebBrowser to IWebBrowser2");
  401.  
  402.             var wbEvents2 = iwb as SHDocVw.DWebBrowserEvents2_Event;
  403.             if (null == wbEvents2) throw new ArgumentException("failed to cast IWebBrowser2 to DWebBrowserEvents2_Event");
  404.  
  405.             if (disable)
  406.             {
  407.                 wbEvents2.FileDownload += OnFileDownload;
  408.             }
  409.             else
  410.             {
  411.                 wbEvents2.FileDownload -= OnFileDownload;
  412.             }
  413.         }
  414.         static void OnFileDownload(bool activeDocument, ref bool cancel) { cancel = true; }
  415.         #endregion
  416.  
  417.         #region DoEvents *do NOT use these methods anymore*
  418.         public static void DoEvents(System.Windows.Forms.WebBrowser browser) { DoEvents(); }
  419.         public static void DoEvents(System.Windows.Controls.WebBrowser browser) { DoEvents(); }
  420.         private static void DoEvents()      // do NOT use this function anymore because it creates weird problems
  421.         {
  422.             var frame = new DispatcherFrame();
  423.             Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
  424.                 new DispatcherOperationCallback(ExitFrame), frame);
  425.             Dispatcher.PushFrame(frame);
  426.         }
  427.         private static object ExitFrame(object f)
  428.         {
  429.             ((DispatcherFrame)f).Continue = false;
  430.  
  431.             return null;
  432.         }
  433.         #endregion
  434.  
  435.         #region NavigateLoadAndRender
  436.         public static bool NavigateLoadAndRender(WebBrowserContext browserContext, string url) { string errMsg; return NavigateLoadAndRender(browserContext, url, out errMsg); }
  437.         public static bool NavigateLoadAndRender(WebBrowserContext browserContext, string url, TimeSpan loadTimeout, TimeSpan renderTime)
  438.         {
  439.             string errMsg = null;
  440.             return NavigateLoadAndRender(browserContext, url, loadTimeout, renderTime, out errMsg);
  441.         }
  442.         public static bool NavigateLoadAndRender(WebBrowserContext browserContext, string url, out string errMsg)
  443.         {
  444.             return NavigateLoadAndRender(browserContext, url,
  445.                 DefaultConfig_BrowserLoadTimeout,
  446.                 DefaultConfig_BrowserRenderTime,
  447.                 out errMsg);
  448.         }
  449.         public static bool NavigateLoadAndRender(WebBrowserContext browserContext, string url, TimeSpan loadTimeout, TimeSpan renderTime, out string errMsg)
  450.         {
  451.             ForceInitActiveXInstance(browserContext);
  452.  
  453.             object axi = null;
  454.             Func<Uri> getBrowserUri = null;
  455.             Action<Uri> navigateBrowser = null;
  456.             Func<IHTMLDocument2> getBrowserDoc = null;
  457.             switch (browserContext.WebBrowserType)
  458.             {
  459.                 case WebBrowserTypeEnum.Forms:
  460.                     {
  461.                         var browser = browserContext.GetWebBrowserAsFormsType();
  462.                         getBrowserUri = () => browser.Url;
  463.                         navigateBrowser = u =>
  464.                         {
  465.                             var finished = false;
  466.                             browserContext.SyncContext.Post(state =>
  467.                             {
  468.                                 browser.Navigate(u);
  469.                                 finished = true;
  470.                             }, null);
  471.                             while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  472.                         };
  473.                         getBrowserDoc = () =>
  474.                         {
  475.                             IHTMLDocument2 doc = null;
  476.                             bool finished = false;
  477.                             browserContext.SyncContext.Post(state =>
  478.                             {
  479.                                 doc = (IHTMLDocument2)browser.Document.DomDocument;
  480.                                 finished = true;
  481.                             }, null);
  482.                             while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  483.  
  484.                             return doc;
  485.                         };
  486.                         axi = GetActiveXInstance(browserContext);
  487.                     }
  488.                     break;
  489.  
  490.                 case WebBrowserTypeEnum.Wpf:
  491.                     {
  492.                         var browser = browserContext.GetWebBrowserAsWpfType();
  493.                         axi = GetActiveXInstance(browser);
  494.                         getBrowserUri = () => browser.Source;
  495.                         navigateBrowser = u =>
  496.                         {
  497.                             var finished = false;
  498.                             browserContext.SyncContext.Post(state =>
  499.                             {
  500.                                 browser.Navigate(u);
  501.                                 finished = true;
  502.                             }, null);
  503.                             while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  504.                         };
  505.                         getBrowserDoc = () =>
  506.                         {
  507.                             IHTMLDocument2 doc = null;
  508.                             bool finished = false;
  509.                             browserContext.SyncContext.Post(state =>
  510.                             {
  511.                                 doc = (IHTMLDocument2)browser.Document;
  512.                                 finished = true;
  513.                             }, null);
  514.                             while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  515.  
  516.                             return doc;
  517.                         };
  518.                         axi = GetActiveXInstance(browserContext);
  519.                     }
  520.                     break;
  521.  
  522.                 default: throw new ArgumentException("unknown browser type", browserContext.WebBrowserType.ToString());
  523.             }
  524.  
  525.             var success = NavigateLoadAndRender(
  526.                 axi, url,
  527.                 getBrowserUri,
  528.                 navigateBrowser,
  529.                 //() => DoEvents(browser),
  530.                 getBrowserDoc,
  531.                 loadTimeout, renderTime, out errMsg);
  532.             return success;
  533.         }
  534.         private static bool NavigateLoadAndRender(object activexInstance, string url,
  535.             Func<Uri> getBrowserUri, Action<Uri> navigateBrowser, /*Action doEvents,*/ Func<IHTMLDocument2> getBrowserDoc,
  536.             TimeSpan loadTimeout, TimeSpan renderTime, out string errMsg)
  537.         {
  538.             errMsg = null;
  539.             var eventHandlerAdded_OnError = false;
  540.             var eventHandlerAdded_OnComlete = false;
  541.             SHDocVw.DWebBrowserEvents2_Event wbEvents2 = null;
  542.             SHDocVw.DWebBrowserEvents2_NavigateErrorEventHandler onError = null;
  543.             SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler onComplete = null;
  544.             try
  545.             {
  546.                 if (null == activexInstance) throw new ArgumentException("activex instance is null");
  547.                 if (string.IsNullOrWhiteSpace(url)) throw new ArgumentException("url is null or whitespace", url);
  548.  
  549.  
  550.                 var iwb = activexInstance as SHDocVw.IWebBrowser2;
  551.                 if (null == iwb) throw new ArgumentException("failed to cast WebBrowser to IWebBrowser2");
  552.  
  553.                 wbEvents2 = iwb as SHDocVw.DWebBrowserEvents2_Event;
  554.                 if (null == wbEvents2) throw new ArgumentException("failed to cast IWebBrowser2 to DWebBrowserEvents2_Event");
  555.  
  556.                 var completed = false;
  557.                 var success = true;
  558.                 var stateLock = new object();
  559.                 onError = delegate(object ppDisp, ref object objUrl, ref object frame, ref object statusCode, ref bool cancel)
  560.                 {
  561.                     var errUrl = (string)objUrl;
  562.                     var browserUri = getBrowserUri();
  563.                     var browserUrl = null == browserUri ? null : browserUri.AbsoluteUri;
  564.                     if (null == errUrl || null == browserUrl) return;
  565.                     if (errUrl.Trim().ToLower() == browserUrl.Trim().ToLower())
  566.                     {
  567.                         lock (stateLock)
  568.                         {
  569.                             success = false;
  570.                             completed = true;
  571.                         }
  572.                     }
  573.                 };
  574.                 onComplete = delegate(object ppDisp, ref object objUrl)
  575.                 {
  576.                     var completeUrl = (string)objUrl;
  577.                     var browserUri = getBrowserUri();
  578.                     var browserUrl = null == browserUri ? null : browserUri.AbsoluteUri;
  579.                     if (null == completeUrl || null == browserUrl) return;
  580.                     if (completeUrl.Trim().ToLower() == browserUrl.Trim().ToLower())
  581.                     {
  582.                         lock (stateLock)
  583.                         {
  584.                             completed = true;
  585.                         }
  586.                     }
  587.                 };
  588.                 wbEvents2.NavigateError += onError; eventHandlerAdded_OnError = true;
  589.                 wbEvents2.DocumentComplete += onComplete; eventHandlerAdded_OnComlete = true;
  590.  
  591.                 navigateBrowser(new Uri(url));
  592.  
  593.                 // wait page load completing
  594.                 var startTime = DateTime.UtcNow;
  595.                 while (!completed)
  596.                 {
  597.                     //doEvents();
  598.                     if (DateTime.UtcNow - startTime > loadTimeout) break;
  599.                     Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  600.                 }
  601.                 if (!success) return success;
  602.  
  603.                 // give rendering a little time, letting scripts/flash load
  604.                 startTime = DateTime.UtcNow;
  605.                 while (DateTime.UtcNow - startTime < renderTime)
  606.                 {
  607.                     //doEvents();
  608.                     Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  609.                 }
  610.  
  611.                 var doc = getBrowserDoc();
  612.                 return ("complete" == doc.readyState.Trim().ToLower() || "interactive" == doc.readyState.Trim().ToLower()) && success;
  613.             }
  614.             catch (Exception e)
  615.             {
  616.                 //errMsg = Logger.WriteLog("WebBrowserUtil.NavigateLoadAndRender", "failed to navigate, load and render.", e);
  617.                 return false;
  618.             }
  619.             finally
  620.             {
  621.                 if (null != wbEvents2)
  622.                 {
  623.                     if (eventHandlerAdded_OnError) wbEvents2.NavigateError -= onError;
  624.                     if (eventHandlerAdded_OnComlete) wbEvents2.DocumentComplete -= onComplete;
  625.                 }
  626.             }
  627.         }
  628.         #endregion
  629.  
  630.         private static void ForceInitActiveXInstance(WebBrowserContext browserContext)
  631.         {
  632.             var axi = GetActiveXInstance(browserContext);
  633.             if (null != axi) return;        // activex instance already initiated
  634.  
  635.             var finished = false;
  636.             var blankPageUri = new Uri(@"about:blank");
  637.             switch (browserContext.WebBrowserType)
  638.             {
  639.                 case WebBrowserTypeEnum.Forms:
  640.                     {
  641.                         var browser = browserContext.GetWebBrowserAsFormsType();
  642.                         browserContext.SyncContext.Post(state =>
  643.                         {
  644.                             browser.Navigate(blankPageUri);
  645.                             finished = true;
  646.                         }, null);
  647.                     }
  648.                     break;
  649.  
  650.                 case WebBrowserTypeEnum.Wpf:
  651.                     {
  652.                         var browser = browserContext.GetWebBrowserAsWpfType();
  653.                         browserContext.SyncContext.Post(state =>
  654.                         {
  655.                             browser.Navigate(blankPageUri);
  656.                             finished = true;
  657.                         }, null);
  658.                     }
  659.                     break;
  660.  
  661.                 default: throw new ArgumentException("unknown browser type", browserContext.WebBrowserType.ToString());
  662.             }
  663.             while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
  664.             Thread.Sleep(DefaultConfig_ActiveXInstanceInitTime);
  665.         }
  666.     }
  667. }
  668.  
  669.  
  670. using System;
  671. using System.Collections.Generic;
  672. using System.Diagnostics;
  673. using System.IO;
  674. using System.Linq;
  675. using System.Text;
  676. using System.Threading;
  677. using System.Threading.Tasks;
  678.  
  679. namespace ConsoleApplication8
  680. {
  681.     class Program
  682.     {
  683.         static void Main(string[] args)
  684.         {
  685.             if (0 == args.Count())
  686.             {
  687.                 var selfExecutable = Path.Combine(Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]), @"ConsoleApplication8.exe");
  688.                 var threadList = new List<Thread>();
  689.                 for (var i = 0; i < 30; i++)
  690.                 {
  691.                     var thread = new Thread(() =>
  692.                     {
  693.                         var startInfo = new ProcessStartInfo(selfExecutable, "--runone");
  694.                         var process = new Process();
  695.                         process.StartInfo = startInfo;
  696.                         process.Start();
  697.  
  698.                         process.WaitForExit();
  699.                     });
  700.                     threadList.Add(thread);
  701.                     thread.Start();
  702.                 }
  703.                 //foreach (var thread in threadList) thread.Start();
  704.                 foreach (var thread in threadList) thread.Join();
  705.             }
  706.             else PrintHtml();
  707.         }
  708.  
  709.         static void PrintHtml()
  710.         {
  711.             var wbc = new WebBrowserUtil.WebBrowserContext(WebBrowserUtil.WebBrowserTypeEnum.Forms);
  712.             WebBrowserUtil.SuppressScriptErrors(wbc, true);
  713.             WebBrowserUtil.DisableFileDownload(wbc, true);
  714.             WebBrowserUtil.BlockNewWindows(wbc, true);
  715.             Console.WriteLine();
  716.             Console.WriteLine("starting navigation, loading and redering");
  717.             var success = WebBrowserUtil.NavigateLoadAndRender(wbc, @"http://news.yahoo.com/obama-white-house-accuses-israel-spying-undermine-iran-124019932.html");
  718.             if (!success)
  719.             {
  720.                 Console.WriteLine("failed to navigate, load and render");
  721.                 return;
  722.             }
  723.  
  724.             var html = WebBrowserUtil.GetDocumentHtml(wbc);
  725.             Console.WriteLine("html:");
  726.             Console.WriteLine(html);
  727.         }
  728.     }
  729. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement