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.
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.
|