VB - Using DownloadFileASync (WebClient) for multiple downloads - vb.net

I'm trying to download multiple files based on what a user has selected on a form.
I have multiple checkboxes in place, so If a user would select Checkboxes 1,3,4 I would want the webclient to download files 1.txt, 3.txt, 4.txt.
The WebClient method is causing a "WebClient does not support concurrent I/O operations." error.
If chk1.Checked Then
WC.DownloadFileAsync(New Uri("http://www.google.com/1.txt), Path.Combine(DataSource & strDirectory, "1.txt"))
End If
If chk2.Checked Then
WC.DownloadFileAsync(New Uri("http://www.google.com/2.txt), Path.Combine(DataSource & strDirectory, "2.txt"))
End If
If chk3.Checked Then
WC.DownloadFileAsync(New Uri("http://www.google.com/3.txt), Path.Combine(DataSource & strDirectory, "3.txt"))
End If
If chk4.Checked Then
WC.DownloadFileAsync(New Uri("http://www.google.com/4.txt), Path.Combine(DataSource & strDirectory, "4.txt"))
End If
I do have a progress bar that tracks the download, as well as a completed event that calls a messagebox.
Private Sub WC_DownloadProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs) Handles WC.DownloadProgressChanged
ProgressBar1.Value = e.ProgressPercentage
End Sub
Private Sub WC_DownloadFileCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs) Handles WC.DownloadFileCompleted
MessageBox.Show("Download complete", "Download", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
How could I go about programming this to download all files checked?
I don't mind if the user only sees that progress bar showing total files downloaded or time remaining, but I do need something to show when all downloads are completed.
Any Suggestions?

I think is because of you using single WebClient instance to execute several HTTP requests at the same time. Try to use several instances.

Related

Process.Start open too many multiple windows

I started to program a couple of months ago and I'm having hard time with Process.Start command.
In the first form I've made a timer that can set a time and opens the program, that i defined it location in my TextBox box (another vb app that i built),
according to the time one enters and presses the "Set" button, when its time it opens the file that you choose.
For some reason it opens 10 multiple windows and on browsing for JPG file, it opens it only once, the multiple windows issues occurs only with .exe files.
Does anyone know the reason?
Here is my code so far:
Public Class startup
Dim iSetTime As Date
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If txtTMinute.Text <> String.Empty Then
Clipboard.SetText(txtTMinute.Text)
Else
Clipboard.Clear()
End If
txtTSecond.Clear()
txtTSecond.Paste()
If (Timer1.Enabled = True) Then
Timer1.Enabled = False
End If
iSetTime = txtTHour.Text + ":" + txtTMinute.Text + ":" + txtTSecond.Text
Timer1.Enabled = True
Label6.Text = "Timer not activated."
Me.Refresh()
System.Threading.Thread.Sleep(1000)
'MessageBox.Show("Activated Succesfully")
Label6.Text = "Timer Activated!"
Label6.ForeColor = Color.Green
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If (TimeOfDay = iSetTime) Then
Process.Start(TextBox1.Text)
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Using ofd As New OpenFileDialog
ofd.Filter = "All files (*.*)|*.*"
ofd.Title = "Select File"
If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then
Me.TextBox1.Text = ofd.FileName
End If
End Using
End Sub
End Class
You don't use enabled = true or false , you use timer.start or timer.stop , i don't know why are you even using a timer to do this? Anywho what's happening is the timer is continously looping through the code after little intervals because IT IS A TIMER and that's what it does until you stop it. If you really want to use a timer for this task then after this line Process.Start(TextBox1.Text) use this code: Timer1.Stop
By the way if you haven't changed the default interval of the timer then it would be set to 100 which is in milliseconds. it is equal to the same time as System.Threading.Thread.Sleep(100) and if you are stopping your timer after System.Threading.Thread.Sleep(1000) then it would've already looped the code: Process.Start(TextBox1.Text) 10 times because 1000/100 = 10
"When im browsing for JPG file, it opens it only once, only with exe
it multiple it."
I'm going to guess that it's trying to open anything you tell it to 10 times, the difference is that when you open an image, it is getting displayed in a single-instance program (like Preview, or Windows Image Viewer, or whatever it happens to be called), and then "reopened" in the same viewer instance 9 more times.
Set a breakpoint at this line:
Process.Start(TextBox1.Text)
When the breakpoint is encountered after running your application in the debugger, mouseover the two variables in the previous line, TimeOfDay and iSetTime in the IDE, and compare their values. I'd be willing to bet you're getting multiple True cases because of the implicit conversion between TimeOfDay's TimeSpan data format, and iSetTime as a Date.

VB.NET Upload to FTP with progressbar

I relise there is so many other questions out there regarding the progressbar, though I've looked through them "all" and can not find one that works.
I am trying to upload c:\screenshot.png to my ftp with a progress bar and a msgbox once finished.
Could someone provide a working example for me?
Thankyou
Edit heres the code I tried. Uploading works, though the progress bar dosent.
Sub UpdateProgressBar(ByVal sender As Object, ByVal e As UploadProgressChangedEventArgs)
If ProgressBar1.InvokeRequired Then
ProgressBar1.Invoke(New UploadProgressChangedEventHandler(AddressOf UpdateProgressBar), sender, e)
Exit Sub
End If
ProgressBar1.Value = CInt(ProgressBar1.Minimum + _
((ProgressBar1.Maximum - ProgressBar1.Minimum) * _
e.ProgressPercentage) / 100)
End Sub
Private Sub btnUpload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click
Label16.Text = "Uploading now..."
Label16.Update()
Dim client As New System.Net.WebClient()
AddHandler client.UploadProgressChanged, AddressOf UpdateProgressBar
With client
.Credentials = New NetworkCredential( _
"damon#slimar.eu", "mine123!")
.UploadFile("ftp://slimar.eu/screenshot.png", "C:\screenshot.png")
End With
Label16.Text = "Done!"
Label16.Update()
End Sub
Progress bar has minValue,Max value, StepValue which is used to perform a step and Value to setup arbitray value.When you uploading a file or downloading you should be able to see via e paramenter total byte and actual byte trasmission.So you can setup Progress bar value and max value.
Also personally i invite you to use backgroundworker which :
Not Freeze GUI
Give you much controll on thread with no issue and no invoke needs
Make it more simple :)

wait for webbrowser to load, then execute code

I have a code that constantly claims a username on a website, so that when the social medium decides to release these usernames I will be the first in line to get it. Now, it does timeout which is a huge problem. So to fix it, I have tried to make it sign out of the account then sign back in.
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If number_of_ticks > NumericUpDown1.Value Then
WebBrowser1.Navigate("https://live.xbox.com/Account/Signout")
While Not WebBrowser1.ReadyState = WebBrowserReadyState.Complete
Application.DoEvents()
End While
WebBrowser1.Navigate("https://live.xbox.com/en-US/ChangeGamertag")
WebBrowser1.Document.GetElementById("login").SetAttribute("value", txtUsername.Text)
WebBrowser1.Document.GetElementById("passwd").SetAttribute("value", txtPassword.Text)
WebBrowser1.Document.GetElementById("SI").InvokeMember("Click")
number_of_ticks = 0
End If
If WebBrowser1.Url.ToString = "https://live.xbox.com/en-US/ChangeGamertag" Then
WebBrowser1.Document.GetElementById("NewGamertag").SetAttribute("value", txtTurbo.Text)
WebBrowser1.Document.GetElementById("claimIt").InvokeMember("Click")
number_of_ticks += 1
Else
End If
End Sub
As you can see, after number_of_ticks reaches a certain number I want it to navigate to the log out page, and then once the web page is fully loaded, navigate to the other page where it puts the info in again to log in. Unfortunately, this doesn't work, and all I get are errors when I try to run this. The code:
While Not WebBrowser1.ReadyState = WebBrowserReadyState.Complete
Application.DoEvents()
End While
seems to not work at all, and especially the other codes such as the WaitForPageLoad.
I have looked for solutions and haven't found ANYTHING.

Saving pdf document from webbrowser control

I'm navigating from webbrowser control to an url like this;
http://www.who.int/cancer/modules/Team%20building.pdf
It's shown in webbrowser control. What I want to do is to download this pdf file to computer. But I tried many ways;
Dim filepath As String
filepath = "D:\temp1.pdf"
Dim client As WebClient = New WebClient()
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadFileAsync(WebBrowserEx1.Url, filepath)
This one downloads a pdf but there is nothing in the file.
Also tried with
objWebClient.DownloadFile()
nothing changed.
I tried to show a save or print dialog;
WebBrowserEx1.ShowSaveAsDialog()
WebBrowserEx1.ShowPrintDialog()
but they didnt show any dialog. Maybe the last one is because it doesnt wait to load the the pdf into webbrowser completely.
When I try html files there is no problem to dowload, but in this .pdf file, I think I didn't manage to wait the file to be loaded as pdf into browser. This function(s);
Private Sub WaitForPageLoad(ByVal adimno As String)
If adimno = "1" Then
AddHandler WebBrowserEx1.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
While Not pageReady
Application.DoEvents()
End While
pageReady = False
End If
End Sub
Private Sub PageWaiter(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs)
If WebBrowserEx1.ReadyState = WebBrowserReadyState.Complete Then
pageReady = True
RemoveHandler WebBrowserEx1.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
End If
End Sub
are not working for this situation. I mean it gets into infinite loop.
So anyone knows how to wait this to load pdf then save into computer.
you could test the URL when document completed fires and if its .pdf, then do the following then navigate back, for example.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
WebBrowserEx1.Navigate("http://www.who.int/cancer/modules/Team%20building.pdf")
End Sub
Private Sub WebBrowserEx1_DocumentCompleted(ByVal sender As Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowserEx1.DocumentCompleted
If WebBrowserEx1.Url.ToString.Contains(".pdf") Then
Using webClient = New WebClient()
Dim bytes = webClient.DownloadData(WebBrowserEx1.Url.ToString) 'again variable here
File.WriteAllBytes(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "TEST.pdf"), bytes) 'save to desktop or specialfolder. to list all the readily available user folders
End Using
'WebBrowserEx1.goback() 'could send browser back a page as well
End If
End Sub
You will need to make the filename "TEST" as a variable instead of a static string or else you will overwrite the same file each time. Perhaps:
WebBrowserEx1.DocumentTitle.ToString & ".pdf"
instead, which would save the file as pdf named by the webpage title. Only problem there is if the page contains illegal characters (that windows doesnt let you save with) it will throw an exception so that should be handled.

How to hide Windows 7 Open File Security when running certain EXE file using VB.NET?

Hello dearest community,
I am trying to build a simple AutoUpdate application using VB.NET. It was quite simple. That is, I put the newest ZIP file in my hosting site, and then download it using WebClient.DownloadFileAsync. After it get downloaded, I extract it using http://stahlforce.com/dev/unzip.exe
But each time I run the unzip.exe using Process.start, Windows 7 always show Open File Security.
Is it possible for VB.NET to bypass such security restriction?
Thanks.
Btw, this is my code of using WebClient.DownloadFileAsync, in case any one google about it and landed on this page :
Public Class AutoUpdate
Dim installationFolder As String = "C:\Program Files\xyz\abc\"
Dim updateFileNameTarget As String
Private Sub btnStartUpdte_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStartUpdte.Click
lblPercent.Text = ""
lblDownloading.Text = ""
lblDownloading.Text = ""
pbDownloadStatus.Value = 0
Dim wc As New WebClient
AddHandler wc.DownloadFileCompleted, AddressOf downloadComplete
AddHandler wc.DownloadProgressChanged, AddressOf progressChanged
Dim path As String = "http://xyz.abc.com/test.zip"
updateFileNameTarget = installationFolder & "test.zip"
Try
If File.Exists(updateFileNameTarget) Then
File.Delete(updateFileNameTarget)
End If
lblDownloading.Text = "Downloading " & path
wc.DownloadFileAsync(New Uri(path), updateFileNameTarget)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub progressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)
pbDownloadStatus.Value = e.ProgressPercentage
lblPercent.Text = e.ProgressPercentage & "%"
End Sub
Private Sub downloadComplete(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
MessageBox.Show("Download complete. Now extracting")
Dim cmd As String = Application.StartupPath & "\Tools\unzip.exe"
Dim arg As String = "-o """ & updateFileNameTarget & """"
Process.Start(cmd, arg)
End Sub
End Class
If you're already process-invoking everything else (including unzip), also use Sysinternal's streams.exe. Use the -d flag to remove the NTFS alternate data streams (ADS). There should only be one - and it is the one that indicates to Windows that the file was downloaded from an "untrusted source".
Your downloaded files will currently have a stream that looks like this:
:Zone.Identifier:$DATA 26
Remove this stream from the download files after extracting but before execution, and the warning will no longer appear.
See also: What is Zone Identifier? - and Accessing alternate data streams in files for a library to work with these within .NET without needing streams.exe.