(MVC) MVC (2018)

DownloadHandler for CefSharp.Winforms.ChromiumWebBrowser.

There are some variants of server response, one of this is with header "content-disposition: attachment":



This is the same response in the real world, and it induce from browser "download" action:



CefSharp.MinimalExample don't contains prototype of any browser reaction to receive same header, and I don't found in internet how to handle this response. But after some experiments I found an interface CefSharp.IDownloadHandler:



If you don't implement this interface at all, you have no receiver in CefSharp.ChromiumWebBrowser and have no sending data from server at all.



So, this is my version of "silent" download handler, that save all request image to path Form1_Instance.TemporaryDir.


   4:  Public Class Form1
   5:   
   6:      Public UrlList As New ArrayList
   7:      Public TemporaryDir As String

My code contains four section. First - a definition and initialisation ChromiumWebBrowser.


   1:  Imports CefSharp.WinForms
   2:  Imports CefSharp
   3:   
   4:   
   5:  Partial Public Class BrowserForm
   6:      Inherits Form
   7:   
   8:      
   9:      Public ReadOnly WebBrowser As ChromiumWebBrowser
  10:   
  11:      Public Sub New()
  12:          InitializeComponent()
  13:          Text = "CefSharp"
  14:          WindowState = FormWindowState.Maximized
  15:          WebBrowser = New ChromiumWebBrowser("about:blank") With {
  16:              .Dock = DockStyle.Fill
  17:          }
  18:   
  19:          toolStripContainer.ContentPanel.Controls.Add(WebBrowser)
  20:          AddHandler WebBrowser.IsBrowserInitializedChanged, AddressOf OnIsBrowserInitializedChanged
  21:          AddHandler WebBrowser.LoadingStateChanged, AddressOf OnLoadingStateChanged
  22:          AddHandler WebBrowser.ConsoleMessage, AddressOf OnBrowserConsoleMessage
  23:          AddHandler WebBrowser.StatusMessage, AddressOf OnBrowserStatusMessage
  24:          AddHandler WebBrowser.TitleChanged, AddressOf OnBrowserTitleChanged
  25:          AddHandler WebBrowser.AddressChanged, AddressOf OnBrowserAddressChanged
  26:          AddHandler WebBrowser.FrameLoadEnd, AddressOf OnFrameLoadEnd
  27:   
  28:          Dim MyDownloadHandler = New DownloadHandler()
  29:          AddHandler MyDownloadHandler.DownloadFinish, AddressOf DownloadComplete
  30:          WebBrowser.DownloadHandler = MyDownloadHandler
  31:   
  32:          Dim bitness = If(Environment.Is64BitProcess, "x64", "x86")
  33:          Dim version = String.Format("Chromium: {0}, CEF: {1}, CefSharp: {2}, Environment: {3}", CefSharp.Cef.ChromiumVersion, CefSharp.Cef.CefVersion, CefSharp.Cef.CefSharpVersion, bitness)
  34:          DisplayOutput(version)
  35:      End Sub

Second part send a request queue in order to download image.


pre> 41: Dim CurrentUrlIndex As Integer
  42:      Dim RequestToLoadImage As Boolean = False
  43:      Public IsLogin As Boolean = False
  44:      Public LoginScript As String = "$('input#username.loginField').val('" & Form1_Instance.LoginTextBox.Text & "');$('input#password.loginField').val('" & Form1_Instance.PassTextBox.Text & "');$('input#loginButton.buttonz').click();"
  45:      Private Sub OnFrameLoadEnd(sender As Object, e As FrameLoadEndEventArgs)
  46:          Dim task As Task = New Task(Sub()
  47:                                          If e.Url.Contains("jotform") Then
  48:                                              If Not IsLogin Then
  49:                                                  Dim LoginScriptResult As Object = EvaluateScript(WebBrowser, LoginScript)
  50:                                                  If LoginScriptResult = "" Then
  51:                                                      IsLogin = True
  52:                                                      Threading.Thread.Sleep(10000)
  53:                                                      RequestToLoadImage = True
  54:                                                      'PrintCookies(e.Url, e.HttpStatusCode, e.Frame, e.Browser)
  55:                                                      'EvaluateScript(WebBrowser, Script1.Value)
  56:                                                  End If
  57:                                              Else
  58:                                                  If e.Url.Contains("https://eu.jotform.com/myforms") And e.HttpStatusCode = 200 Then
  59:                                                      If RequestToLoadImage Then
  60:                                                          If Form1_Instance.UrlList IsNot Nothing Then
  61:                                                              If Form1_Instance.UrlList.Count > 0 Then
  62:                                                                  WebBrowser.Load(Form1_Instance.UrlList(CurrentUrlIndex))
  63:                                                                  RequestToLoadImage = False
  64:                                                                  Application.DoEvents()
  65:                                                                  'Threading.Thread.Sleep(1000)
  66:                                                              End If
  67:                                                          End If
  68:                                                      End If
  69:                                                  End If
  70:                                              End If
  71:                                          End If
  72:                                      End Sub)
  73:          task.Start()
  74:      End Sub

Third part contains my implementation of download handler.


 251:  Public Class DownloadHandler
 252:      Implements CefSharp.IDownloadHandler
 253:   
 254:      Public Delegate Sub DownloadComplete(FullFileName As String, Length As Integer)
 255:      Public Event DownloadFinish As DownloadComplete
 256:      Public FullFileName As String
 257:   
 258:      Public Sub OnBeforeDownload(chromiumWebBrowser As IWebBrowser, browser As IBrowser, downloadItem As DownloadItem, callback As IBeforeDownloadCallback) Implements IDownloadHandler.OnBeforeDownload
 259:   
 260:          If String.IsNullOrEmpty(Form1_Instance.TemporaryDir) Then
 261:              FullFileName = IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), downloadItem.SuggestedFileName)
 262:          Else
 263:              FullFileName = IO.Path.Combine(Form1_Instance.TemporaryDir, downloadItem.SuggestedFileName)
 264:          End If
 265:   
 266:          If Not callback.IsDisposed Then
 267:              Using callback
 268:                  callback.[Continue](FullFileName, showDialog:=False)
 269:              End Using
 270:          End If
 271:      End Sub
 272:   
 273:      Public Sub OnDownloadUpdated(chromiumWebBrowser As IWebBrowser, browser As IBrowser, downloadItem As DownloadItem, callback As IDownloadItemCallback) Implements IDownloadHandler.OnDownloadUpdated
 274:          If downloadItem.ReceivedBytes > 0 Then
 275:              RaiseEvent DownloadFinish(FullFileName, downloadItem.ReceivedBytes)
 276:          End If
 277:      End Sub
 278:   
 279:  End Class

And last part contains handler to process of finish image downloads.


 1077:      Dim RestartLoading As Boolean = True
 1078:      'raise many times to one filename and in another thread
 1079:      Sub DownloadComplete(FullFileName As String, Length As Integer)
 1080:          If IO.Path.GetFileName(FullFileName) = IO.Path.GetFileName(Form1_Instance.UrlList(CurrentUrlIndex)) Then
 1081:              Me.Invoke(New Action(Sub() MessageBox.Show(DownliadedFileList.Count & vbCrLf & FullFileName & vbCrLf & Length & " bytes.")))
 1082:              DownliadedFileList.Add(New With {.FullFileName = FullFileName, .Length = Length})
 1083:              RequestToLoadImage = True
 1084:              If CurrentUrlIndex < Form1_Instance.UrlList.Count - 1 Then
 1085:                  CurrentUrlIndex += 1
 1086:                  Application.DoEvents()
 1087:                  Threading.Thread.Sleep(Form1_Instance.DelayNumericUpDown1.Value)
 1088:                  WebBrowser.Load(Form1_Instance.UrlList(CurrentUrlIndex))
 1089:              End If
 1090:          Else
 1091:              If RestartLoading Then
 1092:                  RestartLoading = False
 1093:                  Application.DoEvents()
 1094:                  Threading.Thread.Sleep(Form1_Instance.DelayNumericUpDown1.Value)
 1095:                  WebBrowser.Load(Form1_Instance.UrlList(0))
 1096:              End If
 1097:          End If
 1098:      End Sub
 1099:   

Let's be careful, this handler working in another thread, so any operation with windows forms need be executed by invoke method.

Comments ( )
Link to this page: //www.vb-net.com/CefSharp_ChromiumWebBrowser_DownloadHandler/index.htm
< THANKS ME>