I'm trying to download a PDF using WebView2.
I can login on the browser but then i would like to download a PDF using WebClient.
But this returns me to the login screen.
Both WebView browsers use the same UserDataFolder.
I would like to download the PDF using the cookie settings used in the WebView2 browser.
Below is a sample that i'm using, but i don't know how to use it.
I believe i'm on the right track...
Private Sub WV_CoreWebView2Ready1(sender As Object, e As EventArgs) Handles WebView_Browser1.CoreWebView2InitializationCompleted
WebView_Browser1.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All)
AddHandler WebView_Browser1.CoreWebView2.WebResourceRequested, AddressOf CoreWebView2_WebResourceRequested
End Sub
Private Sub CoreWebView2_WebResourceRequested(ByVal sender As Object, ByVal e As CoreWebView2WebResourceRequestedEventArgs)
e.Request.Headers.SetHeader("Cookie", XXXXX) <<< i don't know how to use this
Dim addedDate = e.Request.Headers.GetHeader("Cookie")
End Sub
Private Async Sub WebView_Browser2_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs) Handles WebView_Browser2.NavigationCompleted
Dim url As String = pathtourl
Dim fileName As String = "pdf.pdf"
Dim webClient As WebClient = New WebClient()
webClient.Headers.Add(HttpRequestHeader.Cookie, WebView_Browser2.Cookie) <<< use cookie here to login?
webClient.DownloadFileAsync(New Uri(url, UriKind.Absolute), fileName)
End Sub
It would be great i somebody can help me with this!
Thanks!
Update
Dim LoginCookie As String
Private Sub WV_CoreWebView2Ready1(sender As Object, e As EventArgs) Handles WebView_Browser1.CoreWebView2InitializationCompleted
WebView_Browser1.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All)
AddHandler WebView_Browser1.CoreWebView2.WebResourceRequested, AddressOf CoreWebView2_WebResourceRequested
AddHandler WebView_Browser1.CoreWebView2.WebResourceResponseReceived, AddressOf CoreWebView2_WebResourceResponseReceived
End Sub
Private Sub CoreWebView2_WebResourceResponseReceived(ByVal sender As Object, ByVal e As CoreWebView2WebResourceResponseReceivedEventArgs)
LoginCookie = e.Request.Headers.GetHeader("Login")
End Sub
Private Async Sub WebView_Browser2_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs) Handles WebView_Browser2.NavigationCompleted
Dim url As String = pathtourl
Dim fileName As String = "pdf.pdf"
Dim webClient As WebClient = New WebClient()
webClient.Headers.Add(HttpRequestHeader.Cookie, LoginCookie)
webClient.DownloadFileAsync(New Uri(url, UriKind.Absolute), fileName)
End Sub
The Webclient accepts the cookie to be webClient.Headers.Add(HttpRequestHeader.Cookie, "CITY=NY") like this.
But the e.Request.Headers.GetHeader("Login") doesn't get me the cookie.
Again thank you for looking!
You can use this to get the cookies in C# similar pattern for VB.NET
List<CoreWebView2Cookie> cookieList = await WebBrowser.CoreWebView2.CookieManager.GetCookiesAsync(CurrentAddress);
Then loop through to get the string values you are looking for
for (int i = 0; i < cookieList.Count; ++i)
{
CoreWebView2Cookie cookie = TopicWebBrowser.CoreWebView2.CookieManager.CreateCookieWithSystemNetCookie(cookieList[i].ToSystemNetCookie());
cookieResult.Append($"\n{cookie.Name} {cookie.Value} {(cookie.IsSession ? "[session cookie]" : cookie.Expires.ToString("G"))}");
}
Related
Public Class Form1
For i As Integer = 0 To RichTextBox1.Lines.Length - 1
wreq=System.Net.WebRequest.Create("i th Internet address")
wreq.AutomaticDecompression = Net.DecompressionMethods.GZip
wres = wreq.GetResponse
Dim s As System.IO.Stream = wres.GetResponseStream
Dim sr As New System.IO.StreamReader(s)
html = sr.ReadToEnd
s = html.Split(";")
'here is other codes
Next
End Class
this is part of my program.
When I use this, it takes a long time for everyone to download. How can I download all the addresses at the same time?
I found the following code on the internet enter code here to do this, but I do not know how to use it in the my program. Please help. Thank you.
Imports System.Threading.Tasks
Imports System.Net
Imports System.IO
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
'Start a background task so as not to freeze up the UI.
Me.BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim files As String() 'Get file paths.
'Download multiple files simultaneously.
Parallel.ForEach(files,
Sub(f) Call New WebClient().DownloadFile(f,
Path.Combine("local folder here",
Path.GetFileName(f))))
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
MessageBox.Show("All files downloaded")
End Sub
End Class
Take a look on this. Might be a good start (part of your code implemented on each method).
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim urls() As String = RichTextBox1.Lines.Select(Function(url) Trim(url))
Parallel.ForEach(urls, Sub(f)
If Not String.IsNullOrEmpty(f) Then
DownloadAsync(f)
End If
End Sub)
End Sub
Function DownloadAsync(URL As String) As Task(Of Boolean)
Try
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
Dim html As String = ""
Dim result As Boolean
Dim request As HttpWebRequest = HttpWebRequest.Create(URL)
request.AutomaticDecompression = DecompressionMethods.GZip
request.Timeout = 500
request.Method = "GET"
request.UserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0"
Using response As Task(Of WebResponse) = request.GetResponseAsync
If response.Result IsNot Nothing Then
Using ioStream As IO.Stream = response.Result.GetResponseStream
Using sr As New System.IO.StreamReader(ioStream)
html = sr.ReadToEnd
Dim s() As String = html.Split(";"c)
For Each sl In s
Debug.WriteLine(sl)
Next
End Using
result = True
End Using
End If
End Using
Return Task.FromResult(result)
Catch ex As Exception
Debug.WriteLine(ex.Message)
End Try
Return Task.FromResult(False)
End Function
I'm doing a little widget that shows the price of bitcoin using Binance API here
I'm not using Json format as I Just need to parse one string, eventhough I know many of you will say to use json. Anyway, I want to keep the software as simple as possible, but there is a little problem.
I'm downloading the source with webclient and Updating it using a timer.
I think I'm doing a mistake creating every time the new webclient because when I want to move the form, Is not properly mooving even if its not freezing.
The code I'm using is:
Private Sub webclientbtc()
Dim wc As New Net.WebClient
Dim WBTC As IO.Stream = Nothing
wc.Encoding = Encoding.UTF8
WBTC = wc.OpenRead("https://api.binance.com/api/v1/ticker/24hr?symbol=BTCEUR")
Dim btc As String
Using rd As New IO.StreamReader(WBTC)
btc = rd.ReadToEnd
End Using
'---------BTC PRICE---------'
Dim textBefore As String = """lastPrice"":"""
Dim textAfter As String = ""","
Dim startPosition As Integer = btc.IndexOf(textBefore)
startPosition += textBefore.Length
Dim endPosition As Integer = btc.IndexOf(textAfter, startPosition)
Dim textFound As String = btc.Substring(startPosition, endPosition - startPosition)
Dim dNumber As Double = Val(textFound.ToString)
Label1.Text = dNumber.ToString("n2")
'-------------------------------------'
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
webclientbtc()
End Sub
Timer interval is on 1000 ms, which is great to keep me update.
Any idea on how I can avoid the creations of new webclient at every update?
Thanks
Simplified, and using TAP:
Private wc as New WebClient()
Private Async Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Dim s = Await wc.DownloadStringTaskAsync("https://api.binance.com/api/v1/ticker/24hr?symbol=BTCEUR")
Dim d = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(s)
Label1.Text = d("lastPrice")
End Sub
You need to reference newtonsoft json package and imports it, as well as imports system.collections.generic
If the answer by Caius Jard is too good, you can avoid the use of a JSON deserialiser by using a regex:
Imports System.Net
Imports System.Text.RegularExpressions
Public Class Form1
Dim tim As New Timer()
Private Async Sub UpdateBtc(sender As Object, e As EventArgs)
' temporarily disable the timer in case the web request takes a long time
tim.Enabled = False
' using New Uri() makes sure it is a proper URI:
Dim url = New Uri("https://api.binance.com/api/v1/ticker/24hr?symbol=BTCEUR")
Dim rawJson As String
Using wb As New WebClient()
rawJson = Await wb.DownloadStringTaskAsync(url)
End Using
Dim re = New Regex("""lastPrice"":\s*""([0-9.-]+)""")
Dim lastPrice = re.Match(rawJson)?.Groups(1)?.Value
Dim p As Decimal
lblLastPrice.Text = If(Decimal.TryParse(lastPrice, p), p.ToString("N2"), "Fetch error.")
tim.Enabled = True
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
UpdateBtc(Nothing, EventArgs.Empty)
tim.Interval = 3000
AddHandler tim.Tick, AddressOf UpdateBtc
tim.Start()
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
If tim IsNot Nothing Then
tim.Stop()
RemoveHandler tim.Tick, AddressOf UpdateBtc
tim.Dispose()
End If
End Sub
End Class
There's no need to re-use the WebClient, creating it is not what is taking up the time.
I prefer to instantiate timers myself: there is no requirement to do so.
It is better to use descriptive names for controls: "Label1" tells you nothing.
I have a simple button which sends a get request to retrieve a txt file on my website. Problem is it freezes the application while retrieving the info. How can I make it so the application doesn't freeze while waiting for the result?
Private Sub cmd_ClickMe_Click(sender As Object, e As EventArgs) Handles cmd_ClickMe.Click
Dim request As String = String.Format("http://www.*****/database/test.txt")
Dim webClient As New System.Net.WebClient
Dim result As String = webClient.DownloadString(request)
MessageBox.Show(result)
End Sub
I've also tried the following but it doesn't work (says "webClient.DownloadStringAsync(myUri)" does not produce a value:
Private Sub cmd_ClickMe_Click_1(sender As Object, e As EventArgs) Handles cmd_ClickMe.Click
Dim request As String = String.Format("http://www.****.com/database/test.txt")
Dim webClient As New System.Net.WebClient
Dim myUri As Uri = New Uri(request)
Dim result As String = webClient.DownloadStringAsync(myUri)
MessageBox.Show(result)
End Sub
Use DownloadStringAsync(Uri) instead of the DownloadString(uri).
The DownloadStringAsync method does not block the calling thread.
Here is an example how to use it:
Dim wc As New WebClient
' Specify that you get alerted
' when the download completes.
AddHandler wc.DownloadStringCompleted, AddressOf AlertStringDownloaded
Dim uri As New Uri("http:\\changeMe.com") 'Pass the URL to here. This is just an example
wc.DownloadStringAsync(uri)
End Sub
Public Shared Sub AlertStringDownloaded(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
' If the string request went as planned and wasn't cancelled:
If e.Cancelled = False AndAlso e.Error Is Nothing Then
Dim myString As String = CStr(e.Result) 'Use e.Result to get the String
MessageBox.Show(myString)
End If
End Sub
I am trying to create a Windows Phone 7.1 application, basically a currency converter. I am using DownloadStringAsync method to get a short string containing the exchange rate from a specific website. I tested in Visual Studio 2010, DownloadString worked just fine. But not for the phone application. What do I need to do here? I can't really make much sense of it.
Partial Public Class MainPage
Inherits PhoneApplicationPage
Dim webClient As New System.Net.WebClient
Dim a As String
Dim b As String
Dim result As String = Nothing
' Constructor
Public Sub New()
InitializeComponent()
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
a = "USD"
b = "GBP"
webClient = New WebClient
Dim result As String = webClient.DownloadStringAsync(New Uri("http://rate-exchange.appspot.com/currency?from=" + a + "&to=" + b) as String)
TextBox1.Text = result
End Sub
End Class
A few things wrong here:
DownloadStringAsync does not return a value (void method in C# terms)
You need to handle the DownloadStringCompleted event for WebClient variable. You can get the result in the event handler.
You can change your code to something like this to get the above to work:
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
a = "USD"
b = "GBP"
webClient = New WebClient
'Add the event handler here
AddHandler webClient.DownloadStringCompleted, AddressOf webClient_DownloadStringCompleted
Dim url As String = "http://rate-exchange.appspot.com/currency?from=" & a & "&to=" & b
webClient.DownloadStringAsync(New Uri(url))
End Sub
Private Sub webClient_DownloadStringCompleted(ByVal sender as Object,ByVal e as DownloadStringCompletedEventArgs)
TextBox1.Text = e.result
End Sub
Just use DownloadStringTaskAsync:
Using WebClient As WebClient = New WebClient
Return Await WebClient.DownloadStringTaskAsync(New Uri(myurl))
End Using
I am trying to create an updater for my program which automatically download's the latest version of my program from the web. Now I want this process to be done using a progress bar (so when the download progress is at 50% the progress bar is half-way through). This is my code:
Private Sub client_ProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)
Dim bytesIn As Double = Double.Parse(e.BytesReceived.ToString())
Dim totalBytes As Double = Double.Parse(e.TotalBytesToReceive.ToString())
Dim percentage As Double = bytesIn / totalBytes * 100
client.Value = Int32.Parse(Math.Truncate(percentage).ToString())
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim url As String = "MY DOWNLOAD LINK"
'Download
Dim client As WebClient = New WebClient
AddHandler client.DownloadProgressChanged, AddressOf client_ProgressChanged
AddHandler client.DownloadFileCompleted, AddressOf client_DownloadCompleted
client.DownloadFileAsync(New Uri(url), "C:\Users\User\Desktop\BACKUP\TESTING\New folder\1.exe")
End Sub
End Class
Now I know that the place where the file is saved has been inputed manually by me , but I will change that later. My problem currently is that the file is not being downloaded. However when I change the DownloadFileAsync method to DownloadFile , my program downloads the file. However with the DownloadFile method I will not be able to use the progress bar to track the download progress. Any help is much appreciated :-)
Don't know what you mean, when you say that the file isn't downloaded? You get an Error/Exception? Nothing happens at all? Did you place breakpoints, debug.prints etc?
With VS2012 and asyn/await you can put everything into one method an keep a "linear code-flow". Import System.Threading and System.Threading.Tasks
Private Async Function DownloadWithProgress(ByVal url As String, ByVal p As ProgressBar) As Task(Of Integer)
Dim wc As Net.HttpWebRequest = DirectCast(Net.HttpWebRequest.Create(url), Net.HttpWebRequest)
Dim resp = Await (New TaskFactory(Of Net.WebResponse)).StartNew(AddressOf wc.GetResponse)
p.Value = 0
p.Maximum = CInt(resp.ContentLength)
Dim rqs = resp.GetResponseStream
Dim bufsize As Integer = 1 << 16
Dim buffer(bufsize) As Byte
Dim got As Integer = 0
Dim total As Integer = 0
Do
got = Await (New TaskFactory(Of Integer)).FromAsync(AddressOf rqs.BeginRead, AddressOf rqs.EndRead, buffer, 0, bufsize, Nothing)
total += got
Me.Label1.Text = "got: " & total.ToString
p.Increment(got)
Loop Until got = 0
Return total
End Function
In this sample, the data from the web is downloaded into an array, but you can of course also write it into a file, or do whatever you want with the data.
Sample for usage:
Private running As Boolean = False
Private Async Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
If running Then
MessageBox.Show("Cant you see, I'm working?")
Exit Sub
Else
running = True
End If
Await DownloadWithProgress("http://download.thinkbroadband.com/5MB.zip", ProgressBar1)
running = False
End Sub