Hi I am trying to add a progress bar to a FTP image upload, though I looked at many examples over the internet and I've tried numerous things but just couldn't get anything to work with my following code. I want a progress bar to track the progress of the upload then show 100% once done.
My coding:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim s As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
Static r As New Random
Dim sb As New StringBuilder
For i As Integer = 1 To 8
Dim idx As Integer = r.Next(0, 35)
sb.Append(s.Substring(idx, 1))
Next
Clipboard.SetText("http://my-site.com/osdf/" + sb.ToString() + ".png")
Using ms As New System.IO.MemoryStream
sc.CaptureDeskTopRectangle(Me.boundsRect).Save(ms, System.Drawing.Imaging.ImageFormat.Png)
''Close()
Using wc As New System.Net.WebClient
AddHandler wc.UploadDataCompleted, AddressOf UploadCompleted
wc.UploadData("ftp://USERNAME:PASSWORD#My-site.com/pic/uploads/" + sb.ToString() + ".png", ms.ToArray())
End Using
MsgBox("File Uploaded", MsgBoxStyle.Information)
End Using
End Sub
How would I be able to do this using my code?
Thanks in advance, I will appreciate your support.
Change your code and use the WebClient event like:
Using wc As New System.Net.WebClient
AddHandler wc.UploadDataCompleted, AddressOf wc_UploadDataCompleted
AddHandler wc.UploadProgressChanged, AddressOf wc_UploadProgressChanged
wc.UploadData("ftp://USERNAME:PASSWORD#My-site.com/pic/uploads/" & sb.ToString() & ".png", ms.ToArray())
End Using
Also you need:
Private Sub wc_UploadDataCompleted(sender As Object, e As System.Net.UploadDataCompletedEventArgs)
MsgBox("File Uploaded", MsgBoxStyle.Information)
End Sub
Private Sub wc_UploadProgressChanged(sender As Object, e As System.Net.UploadProgressChangedEventArgs)
ProgressBar1.Value = e.ProgressPercentage
End Sub
you will need to use "UploadDataAsync" instead of "UploadData" to be able to see the increament in the progressbar or use a BackgroundWorker with UploadData method.
Related
I'm trying to load a new webpage through the control webview2 in .net6+ windows forms, and I'm using a listbox to extract any single item and add it to the url to load on webview.
For example in listbox I have:
11
22
33
44
55
I would like at the press of a button that a loop starts to load one by one,each of these items like
WebView21.Source = New Uri("https://google.it" & ListBox1.Items.first & "rest of the url")
and after the webpage is loaded, it s supposed to extract it's html to check if a certain string is present with
Dim html As String
html = Await WebView21.ExecuteScriptAsync("document.documentElement.outerHTML;")
If html.Contains("Not found") Then
MsgBox("In Vacanza")
Else
MsgBox("Attivo")
End If
End Sub
after that, it goes back to the second listbox item, load the webview, check the html and so on.
My question is how can I loop the WebView in order to pick each of the items one by one and to proceed to do these little things in the while?
p.s. Once the loop arrives to the last listbox item, would it be possible to start it again from the first item?
Much thanks
edit1:
I'm trying with
Private ReadOnly resetEvent As New ManualResetEvent(False)
Async Sub scanWeb()
For Each listBoxElem As String In ListBox1.Items
resetEvent.Reset()
AddHandler WebView2.CoreWebView2.NavigationCompleted, AddressOf OnNavigationCompleted
WebView2.Source = New Uri("https://ikalogs.ru/tools/map/?page=1&server=22&world=10&state=active&search=city&allies%5B1%5D=&allies%5B2%5D=&allies%5B3%5D=&allies%5B4%5D=&nick=" & listBoxElem & "&ally=&island=&city=&x=&y=")
Await Task.Run(Sub() resetEvent.WaitOne())
RemoveHandler WebView2.CoreWebView2.NavigationCompleted, AddressOf OnNavigationCompleted
Dim html As String
html = Await WebView2.ExecuteScriptAsync("document.documentElement.outerHTML;")
If html.Contains("Not found") Then
DataGridView1.Rows.Add(listBoxElem, "IN vacanza")
Else
DataGridView1.Rows.Add(listBoxElem, "Attivo")
End If
Next
End Sub
Private Sub OnNavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs)
resetEvent.Set()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
WebView2 = New WebView2()
WebView2.EnsureCoreWebView2Async()
End Sub
but it seems the loop doesn't wait for the process to end and it goes straight to the next listbox item...
best way is to enumerate listBox items in a for-each loop : (I added an escape way -simple mouse clic on form - to quit loop)
Dim wStop As Boolean
sub scanWeb()
Do
For Each listBoxElem As String In ListBox1.Items
WebView21.Source = New Uri("https://google.it" & listBoxElem & "rest of the url")
'etc....
Next
Loop Until wStop = True
wStop = False
end sub
'way to stop scan
Private Sub form_clic(sender As Object, e As MouseEventArgs) Handles MyBase.MouseClick
wStop = True
End Sub
*** Update *****
The webview2 control is rather made to display data, and I have no experience on it.
Also I suggest you use a simpler method, based on System.Net.WebClient() and associated with threading.
Here is a start of code that works:
Dim wStop As Boolean
Dim i As Integer = 0
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim BackProcess = New Thread(Sub() Me.scanWeb())
BackProcess.Priority = ThreadPriority.Normal
BackProcess.Start()
end sub
Sub scanWeb()
Do While Not wStop
Dim WC As New System.Net.WebClient()
'change url for your need
Dim url As String = "https://www.google.fr/search?q=" & ListBox1.Items(i)
Dim s As System.IO.Stream = WC.OpenRead(url)
Dim sr As New System.IO.StreamReader(s)
Dim html As String = sr.ReadToEnd()
If html.Contains("Not found") Then 'beginInvoke allows the back task to communicate with UI
Me.BeginInvoke(Sub() DataGridView1.Rows.Add(ListBox1.Items(i), "In vacanza"))
Else
Me.BeginInvoke(Sub() DataGridView1.Rows.Add(ListBox1.Items(i), "Attivo"))
End If
i += 1
If i > ListBox1.Items.Count - 1 Then i = 0
Loop
End Sub
'button event to stop scanning
Private Sub stopScan_Click(sender As Object, e As EventArgs) Handles stopScan.Click
wStop = True
End Sub
I'm trying to put my External IP in a Label, so I'm downloading the result based on a site, but the moment I change my IP via VPN, the application crashes, I believe it's because it does not check if it's getting the string down, that he tried.
On form load...
If Label1.Text = LastIp Then
Try
Dim wc As New WebClient
Label1.Text = wc.DownloadString("http://icanhazip.com/")
If you can not then
Label.Text = "Failed to get IP"
End if
End If
Form...
You could set up a callback and specify the path to the file:
Dim wc As New WebClient
AddHandler wc.DownloadStringCompleted, AddressOf DownloadStringComplete
wc.DownloadStringAsync(New Uri("http://icanhazip.com/myfile.txt", UriKind.Absolute))
Private Sub DownloadStringComplete(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
If Not IsNothing(e.Error) Then
Label1.Text = e.Error.Message
ElseIf e.Cancelled Then
Label1.Text = "canceled"
Else
Label1.Text = e.Result
End If
End Sub
I have two codes here separately it works but when i put it together i get the error "Cross-thread operation not valid". i tried to search the web how to solve this, i just don't get how to apply it in my codes.
Cross-Thread operation not valid VB.NET
http://forums.asp.net/t/1467258.aspx?Error+Cross+thread+operation+not+valid+Control+Listbox1+accessed+from+a+thread+other+than+the+thread+it+was+created+on+
CODE 1 use to Screen Shot my PANEL control.
Private Sub CaptureSHOT(ctrl As Control, fileName As String)
Dim bounds As Rectangle = ctrl.Bounds
Dim pt As Point = ctrl.PointToScreen(bounds.Location)
Dim bitmap As New Bitmap(bounds.Width, bounds.Height)
Using g As Graphics = Graphics.FromImage(bitmap)
g.CopyFromScreen(New Point(pt.X - ctrl.Location.X, pt.Y - ctrl.Location.Y), Point.Empty, bounds.Size)
End Using
bitmap.Save(fileName, ImageFormat.Png)
End Sub
CODE 2 use to call my "CaptureShot" Function via timer when the FORM loads.
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
MyBase.OnLoad(e)
Dim tmr As New System.Timers.Timer()
tmr.Interval = 2000
tmr.Enabled = True
tmr.Start()
AddHandler tmr.Elapsed, AddressOf OnTimedEvent
End Sub
Private Delegate Sub CloseFormCallback()
Private Sub CloseForm()
If InvokeRequired Then
Dim d As New CloseFormCallback(AddressOf CloseForm)
Invoke(d, Nothing)
Else
Close()
End If
End Sub
Private Sub OnTimedEvent(ByVal sender As Object, ByVal e As ElapsedEventArgs)
CaptureSHOT(Panel1, "D:\SC\" & erk & ".png")
CloseForm()
End Sub
The Error i'm getting
Geez you're all hostile today haha kidding aside thanks to Enigmativity and varocarbas strict lecture i notice that i already have a "Private Delegate Sub" for my CloseFormCallback() and i keep getting an error because i was adding another "Private Delegate Sub" for my "CaptureShot" Function. now i just add the "CaptureSHOT(Panel1, "D:\SC\" & erk & ".png")" to my Private Delegate Sub CloseFormCallback(). and it works!
Private Delegate Sub CloseFormCallback()
Private Sub CloseForm()
If InvokeRequired Then
Dim d As New CloseFormCallback(AddressOf CloseForm)
Invoke(d, Nothing)
Else
CaptureSHOT(Panel1, "D:\SC\" & erk & ".png")
Close()
End If
End Sub
I trying to write an app to download 2 files, I'm able to download the 2 files with the code below:
Dim client As WebClient = New WebClient
AddHandler client.DownloadProgressChanged, AddressOf client_ProgressChanged
AddHandler client.DownloadFileCompleted, AddressOf client_DownloadCompleted
client.DownloadFileAsync(New Uri("http://URL.com/Myfile.exe"), "..\MyFile.exe")
Button1.Text = "Download in Progress"
Button1.Enabled = False
Dim client2 As WebClient = New WebClient
AddHandler client2.DownloadProgressChanged, AddressOf client_ProgressChanged
AddHandler client2.DownloadFileCompleted, AddressOf client_DownloadCompleted
client2.DownloadFileAsync(New Uri("http://URL.com/Myfile2.exe"), "..\MyFile2.exe")
Problem I'm having is that the progress bar is not showing total download progress for both files. It shows one, then a few seconds later shows the other one and keeps switching between both.
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
ProgressBar.Value = Int32.Parse(Math.Truncate(percentage).ToString())
Label1.Text = "Downloaded: " & bytesIn & " of " & totalBytes
Label2.Text = String.Format("{0:00}", percentage) & "%"
End Sub
Anyone know how I can make the progressbar have the values of both downloads combined? Or maybe how I can tell it to wait for the first download then start the second?
You simply need to keep track of progress for each WebClient. Total progress is going to be 200%. Solving it for the general case:
Dim progress As Dictionary(Of WebClient, Integer)
Sub StartDownloads()
progress = new Dictionary(Of WebClient, Integer)
Dim client As WebClient = New WebClient()
progress.Add(client, 0)
'' etc..
End Sub
Private Sub client_ProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)
progress(DirectCast(sender, WebClient)) = e.ProgressProcent
Dim total As Integer = 0
For Each client In progress.Keys
total += progress(client)
Next
ProgressBar.Value = total \ progress.Count
End Sub
Untested, ought to be close.
To make it load one file at a time, use a List(Of String) for all the files names. Start the process using the first element(filename) use the completed event and remove that file name and the addhandler for the completed event. Then check if there are more files in the List(Of String) then charge up a new WebClient for that one - rinse repeat.
Private files As New List(Of String)
'fill this with the file names(URIs) then start the process
Private Sub DownloadFile()
Dim client As New WebClient
AddHandler client.DownloadProgressChanged, AddressOf client_ProgressChanged
AddHandler client.DownloadFileCompleted, AddressOf client_DownloadCompleted
client.DownloadFileAsync(New Uri(files(0), "some destination path")
End Sub
Private Sub client_DownloadCompleted(...)
RemoveHandler client.DownloadProgressChanged, AddressOf client_ProgressChanged
RemoveHandler client.DownloadFileCompleted, AddressOf client_DownloadCompleted
files.RemoveAt(0)
If files.Count > 0 Then DownloadFile()
End Sub
I just made a ftp chat in vb.net and it update message from a file from a ftp server
so i add a timer with interval 1000 with this code
Try
Dim client As New Net.WebClient
client.Credentials = New Net.NetworkCredential("fnet_1355****", "******")
RichTextBox1.Text = client.DownloadString("ftp://185.**.***.**/htdocs/chat.txt")
Catch ex As Exception
End Try
so .. the file is downloaded and it update the text successful but there is a problem .. every time he download the form have a bit lag ... and i dont like that :D what i can do ?
RichTextBox1.Text = client.DownloadString("ftp://185.**.***.**/htdocs/chat.txt")
Instead of this try async method.
client.DownloadStringAsync(new Uri("ftp://185.**.***.**/htdocs/chat.txt"))
and then handle download string completed event.
Sample Code
client.DownloadStringAsync(new Uri("ftp://185.**.***.**/htdocs/chat.txt"));
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
RichTextBox1.Text =e.Result;
}
You can also add progress indicator by handling progress change event.
The best way you can do it would be to use ThreadPool provided by the Framework to I/O bound operation on different thread.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf DownloadFromFtp))
End Sub
Private Sub DownloadFromFtp()
Try
Dim client As New Net.WebClient
client.Credentials = New Net.NetworkCredential("fnet_1355****", "******")
Dim response As String = client.DownloadString("ftp://185.**.***.**/htdocs/chat.txt")
Me.Invoke(New MethodInvoker(Function() RichTextBox1.Text = response))
Catch ex As Exception
End Try
End Sub
This program was the exact one I design before i learned PHP.
Here try this:
Dim thrd As Threading.Thread
Dim tmr As New Timer
Dim tempstring As String
Private Sub thread_start()
thrd = New Threading.Thread(Sub() check_for_changes())
tmr.Interval = 50
AddHandler tmr.Tick, AddressOf Tick
tmr.Enabled = True
tmr.Start()
thrd.Start()
End Sub
Private Sub Tick(sender As Object, e As EventArgs)
If Not thrd.IsAlive Then
tmr.Stop() : tmr.Enabled = False
RichTextBox1.Text = tempstring
End If
End Sub
Private Sub check_for_changes()
Try
Dim client As New Net.WebClient
client.Credentials = New Net.NetworkCredential("fnet_1355****", "******")
tempstring = client.DownloadString("ftp://185.**.***.**/htdocs/chat.txt")
Catch ex As Exception
End Try
End Sub
Hope It Helps.