Download File With Start / Pause / Stop - vb.net

Is there any way i can pause a file download in my vb program?? I have tried both the http method and the my.computer.net method with no luck. I have also tried pausing the background worker by this method: [URL] But even if the bgworker is paused the download goes on.....
Dim locationfiledownload As String
Dim whereToSave As String 'Where the program save the file
Delegate Sub ChangeTextsSafe(ByVal length As Long, ByVal position As Integer, ByVal percent As Integer, ByVal speed As Double)
Delegate Sub DownloadCompleteSafe(ByVal cancelled As Boolean)
Public Sub DownloadComplete(ByVal cancelled As Boolean)
ToolStripButton2.Enabled = True
ToolStripButton3.Enabled = False
If cancelled Then
Me.Label4.Text = "Cancelled"
MessageBox.Show("Download aborted", "Aborted", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
Me.Label4.Text = "Successfully downloaded"
MessageBox.Show("Successfully downloaded!", "All OK", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
Me.RadProgressBar1.Value1 = 0
Me.Label4.Text = ""
End Sub
Public Sub ChangeTexts(ByVal length As Long, ByVal position As Integer, ByVal percent As Integer, ByVal speed As Double)
Me.Label4.Text = "Downloaded " & Math.Round((position / 1024), 2) & " KB of " & Math.Round((length / 1024), 2) & "KB"
Me.RadProgressBar1.Value1 = percent
End Sub
Public Sub btnDownload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton2.Click
locationfiledownload = GetPage("http://asankonkur.ir/update/locationfiledownload.txt")
If locationfiledownload <> "" AndAlso locationfiledownload.StartsWith("http://") Then
Me.SaveFileDialog1.FileName = locationfiledownload.Split("/"c)(locationfiledownload.Split("/"c).Length - 1)
If Me.SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
Me.whereToSave = Me.SaveFileDialog1.FileName
Me.SaveFileDialog1.FileName = ""
ToolStripButton2.Enabled = False
ToolStripButton3.Enabled = True
Me.BackgroundWorker2.RunWorkerAsync() 'Start download
End If
Else
MessageBox.Show("Please insert valid URL for download", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
End Sub
Private Sub BackgroundWorker2_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker2.DoWork
'Creating the request and getting the response
Dim theResponse As HttpWebResponse
Dim theRequest As HttpWebRequest
Try 'Checks if the file exist
theRequest = WebRequest.Create(locationfiledownload)
theResponse = theRequest.GetResponse
Catch ex As Exception
MessageBox.Show("An error occurred while downloading file. Possibe causes:" & ControlChars.CrLf & _
"1) File doesn't exist" & ControlChars.CrLf & _
"2) Remote server error", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Dim cancelDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)
Me.Invoke(cancelDelegate, True)
Exit Sub
End Try
Dim length As Long = theResponse.ContentLength 'Size of the response (in bytes)
Dim safedelegate As New ChangeTextsSafe(AddressOf ChangeTexts)
Me.Invoke(safedelegate, length, 0, 0, 0) 'Invoke the TreadsafeDelegate
Dim writeStream As New IO.FileStream(Me.whereToSave, IO.FileMode.Create)
'Replacement for Stream.Position (webResponse stream doesn't support seek)
Dim nRead As Integer
'To calculate the download speed
Dim speedtimer As New Stopwatch
Dim currentspeed As Double = -1
Dim readings As Integer = 0
Do
If BackgroundWorker2.CancellationPending Then 'If user abort download
Exit Do
End If
speedtimer.Start()
Dim readBytes(4095) As Byte
Dim bytesread As Integer = theResponse.GetResponseStream.Read(readBytes, 0, 4096)
nRead += bytesread
Dim percent As Short = (nRead * 100) / length
Me.Invoke(safedelegate, length, nRead, percent, currentspeed)
If bytesread = 0 Then Exit Do
writeStream.Write(readBytes, 0, bytesread)
speedtimer.Stop()
readings += 1
If readings >= 5 Then 'For increase precision, the speed it's calculated only every five cicles
currentspeed = 20480 / (speedtimer.ElapsedMilliseconds / 1000)
speedtimer.Reset()
readings = 0
End If
Loop
'Close the streams
theResponse.GetResponseStream.Close()
writeStream.Close()
If Me.BackgroundWorker2.CancellationPending Then
IO.File.Delete(Me.whereToSave)
Dim cancelDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)
Me.Invoke(cancelDelegate, True)
Exit Sub
End If
Dim completeDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)
Me.Invoke(completeDelegate, False)
End Sub
Private Sub mainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Label4.Text = ""
End Sub
Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton3.Click
Me.BackgroundWorker2.CancelAsync() 'Send cancel request
End Sub

In your code, you are using WebRequest.Create(locationfiledownload). By default, this creates a request header that asks for the entire file. You need to edit the request and add a Range header that asks for the specific byte range of the file you're looking for. E.g., adding to the WebRequest.Headers.Range.Ranges collection. Unfortunately, this is going to make your code quite a bit more complex as you will need to store details of what's already been download somewhere (assuming you want to resume after application close/restart). You'll need to know;
How much of the file (if any) is already downloaded
How much you intend downloading at any one time
Once you know this, you will have to form a request with a Range header for X bytes of the file. Once you receive it, you'll need to save it and ask for the next section. An example written in C# is available on The Code Project here: http://www.codeproject.com/Tips/307548/Resume-Suppoert-Downloading

Related

Access the same file from different backgroundworker instances

I need some little assistance!
Ive spent several days looking for a solution, so far seems that no one has encountered this wall.
Ive created a file transfer that moves files from a specified server to other PCs within the network, this app is user by 5 people, and the issue I am facing here is that if one person is accessing this file and it is being copied, all other 4 programs get rendered useless until that transfer is completed, this said, no error is displayed and the 4 programs (running on different machines) go directly to the "RunWorkerCompleted" procedure and thats it, I get it that the file is being used and therefore is locked, but is there a way to force the backgroundworker not to lock the file?
here is the entire code used on my project:
Private w101 As String
Private SaveDir As String
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim parts As String() = w101.Split(New Char() {"\"c})
Dim filename As String = parts(parts.Count - 1)
Dim streamRead As New System.IO.FileStream(w101, System.IO.FileMode.Open, IO.FileAccess.ReadWrite, IO.FileShare.Read)
Dim streamWrite As New System.IO.FileStream(SaveDir + "\" + filename, IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.None)
Dim lngLen As Long = streamRead.Length - 1
Dim lnglenres As Long = lngLen / 1048576
Dim byteBuffer(4096) As Byte
Dim intBytesRead As Integer
setLabelTxt1("STATUS : (0/" + (lnglenres * 1).ToString + " MB) Transferred.", KITTASK_media1progress)
Try
While (streamWrite.Length < streamRead.Length)
If (BackgroundWorker1.CancellationPending = True) Then
e.Cancel = True
Exit While
End If
BackgroundWorker1.ReportProgress(CLng(streamRead.Position / lngLen * 100))
setLabelTxt1("STATUS : (" + CLng(streamRead.Position / 1048576).ToString + " MB / " + (lnglenres * 1).ToString + " MB) Transferred.", KITTASK_media1progress)
intBytesRead = (streamRead.Read(byteBuffer, 0, 4096))
streamWrite.Write(byteBuffer, 0, intBytesRead)
End While
streamWrite.Flush()
streamWrite.Close()
streamRead.Close()
Catch ex As Exception
MessageBox.Show("ERROR: " & ex.Message)
End Try
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
On Error Resume Next
ProgressBar1.Value = e.ProgressPercentage
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
On Error Resume Next
If e.Cancelled = True Then
MsgBox("File transfer cancelled by user.")
ProgressBar1.Value = 0
KITTASK_media1progress.Text = "STATUS : Ready"
Else
MsgBox("1 ok")
ProgressBar1.Value = 0
KITTASK_media1progress.Text = "STATUS : Ready"
End If
End Sub
any help is greatly appreciated! thank you for taking the time to read this post.

Reading and writing files causes "The process cannot access the file because it is being used by another process" error

I'm very new to coding so my code is very basic but I am trying to rewrite a file using an item selected from a list box. The code is a recreation of my full code so it's not as thorough but I want to be able to change the "availability" of a product for a website (In theory because this is not a professional project). When I try to read or write the file an error message comes up saying "The process cannot access the file because it is being used by another process".
Dim FileRewrite As String = "FileRewrite.txt"
Dim ValidateID As Boolean
Dim Read As String
Dim IDR As String
Dim YNR As String
Private Sub TxtBxID_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TxtBxID.TextChanged
If TxtBxID.Text.Length = 2 Then
ValidateID = True
Else
ValidateID = False
End If
End Sub
Private Sub BtnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnAdd.Click
Dim ID As String
Dim YN As String
Dim Writer As New System.IO.StreamWriter(FileRewrite, True)
If ValidateID = True Then
ID = TxtBxID.Text
If CBxYN.Checked = True Then
YN = "YES"
Else
YN = "NO "
End If
Writer.WriteLine(LSet(ID, 3) & LSet(YN, 3))
Writer.Close()
LstBxItems.Items.Clear()
Dim Reader As New System.IO.StreamReader(FileRewrite, True)
Do While Reader.Peek >= 0
LstBxItems.Items.Add(Reader.ReadLine)
Loop
Reader.Close()
Else
MsgBox("Please enter a 2 digit ID")
End If
End Sub
Private Sub BtnChange_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnChange.Click
Dim ItemToChange As String
Dim Reader As New System.IO.StreamReader(FileRewrite, True)
ItemToChange = LstBxItems.SelectedItem
IDR = Mid(ItemToChange, 1, 3)
YNR = Mid(ItemToChange, 4, 6)
Do While Reader.Peek >= 0
Read = Reader.ReadLine
Writer()
Loop
Reader.Close()
End Sub
Private Sub Writer()
Dim Writer As New System.IO.StreamWriter(FileRewrite, True)
If Mid(Read, 1, 3) = IDR Then
If YNR = "YES" Then
YNR = "NO "
Else
YNR = "YES"
End If
Writer.WriteLine(LSet(IDR, 3) & LSet(YNR, 3))
Writer.Close()
End If
End Sub
I expect the availability of the product in the file to change from yes to no or no to yes but the reader and writer will not work
You cannot write to the file while looping through the same file to read via Reader.Peek

tcpclient webrelay and control analog outputs

This is the first time that I have ever worked with networking in a program control webrelay. I was able to write my program with success... or so I thought. A couple of days ago I had a device drop off the network and my program "locked up". I know it did not truly lock up. I did some debugging and found out that what is happening is that when the tcpclient throws an exception, it just stops running any code after it. This causes my program to stop updating because of a timer that is never restarted and I con't control analog Outputs.
Public Class ControlPanelX317
Private SQL As New SQLControl
Private Sub ControlPanelX317_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LoadControlsX317()
End Sub
'Dislay Conrol
'__________________________________________________________________________________________________________________________________________________________________________
Private Sub LoadControlsX317()
Dim loadqry As String = "SELECT * FROM controlsX317 WHERE controlsX317.ValueVoltageID = '" & 1 & "' "
Dim SQLCmd As New SqlCommand(loadqry, Sql.SQLCon)
If Sql.SQLCon.State = ConnectionState.Closed Then Sql.SQLCon.Open()
Dim reader As SqlDataReader = SQLCmd.ExecuteReader
While reader.Read = True
txt_S1_VolueVoltage.Text = reader("S1VolueVoltage")
txt_S2_VolueVoltage.Text = reader("S2VolueVoltage")
txt_S3_VolueVoltage.Text = reader("S3VolueVoltage")
txt_S4_VolueVoltage.Text = reader("S4VolueVoltage")
End While
SQLCmd.Dispose()
reader.Close()
Sql.SQLCon.Close()
End Sub
Private Sub btn_Save_ValueVoltage_Click(sender As Object, e As EventArgs) Handles btn_Save_ValueVoltage.Click
If txt_S1_VolueVoltage.Text > 10 Then
MsgBox("Max Voltage is 10V")
txt_S1_VolueVoltage.Clear()
Exit Sub
End If
If txt_S2_VolueVoltage.Text > 10 Then
MsgBox("Max Voltage is 10V")
txt_S2_VolueVoltage.Clear()
Exit Sub
End If
If txt_S3_VolueVoltage.Text > 10 Then
MsgBox("Max Voltage is 10V")
txt_S3_VolueVoltage.Clear()
Exit Sub
End If
If txt_S4_VolueVoltage.Text > 10 Then
MsgBox("Max Voltage is 10V")
txt_S4_VolueVoltage.Clear()
Exit Sub
End If
If txt_S1_VolueVoltage.Text <> "" Then
Dim UpdateValueVoltage As String = "UPDATE controlsX317 SET S1VolueVoltage='" & txt_S1_VolueVoltage.Text & "', S2VolueVoltage='" & txt_S2_VolueVoltage.Text & "',
S3VolueVoltage='" & txt_S3_VolueVoltage.Text & "', S4VolueVoltage='" & txt_S4_VolueVoltage.Text & "'
WHERE ValueVoltageID ='" & 1 & "' "
If SQL.DataUpdate(UpdateValueVoltage) = 0 Then
MsgBox("The Sysytem could not be found!!! ")
Else
MsgBox("VolueVoltage successfully changed")
End If
Else
MsgBox("You must restart a Sysytem")
End If
End Sub
Private Sub btn_S1_SetVoltage_Click(sender As Object, e As EventArgs) Handles btn_S1_SetVoltage.Click
lbl_S1_AnalogOutput.Text = Val(txt_S1_VolueVoltage.Text) * Val(txt_S1_ControlViltage.Text / 100) & "V"
End Sub
Private Sub btn_S2_SetVoltage_Click(sender As Object, e As EventArgs) Handles btn_S2_SetVoltage.Click
lbl_S2_AnalogOutput.Text = Val(txt_S2_VolueVoltage.Text) * Val(txt_S2_ControlViltage.Text / 100) & "V"
End Sub
Private Sub btn_S3_SetVoltage_Click(sender As Object, e As EventArgs) Handles btn_S3_SetVoltage.Click
lbl_S3_AnalogOutput.Text = Val(txt_S3_VolueVoltage.Text) * Val(txt_S3_ControlViltage.Text / 100) & "V"
End Sub
Private Sub btn_S4_SetVoltage_Click(sender As Object, e As EventArgs) Handles btn_S4_SetVoltage.Click
lbl_S4_AnalogOutput.Text = Val(txt_S4_VolueVoltage.Text) * Val(txt_S4_ControlViltage.Text / 100) & "V"
End Sub
'End Display Control
'_________________________________________________________________________________________________________________________________________________________________________
'Conection to WebRelay X317
'_________________________________________________________________________________________________________________________________________________________________________
Public Sub getWebRelayState()
Dim tcpClient As New TcpClient()
Dim port As Integer
Try
port = Convert.ToInt32(txtPort.Text)
tcpClient.Connect(txt_IPAddress.Text, port)
If tcpClient.Connected Then
'Create a network stream object
Dim netStream As NetworkStream = tcpClient.GetStream()
'If we can read and write to the stream then do so
If netStream.CanWrite And netStream.CanRead Then
'Send the on command to webrelay
Dim sendBytes As Byte() = Encoding.ASCII.GetBytes("GET /state.xml?noReply=0 HTTP/1.1" & vbCrLf & "Authorization: Basic bm9uZTp3ZWJyZWxheQ==" & vbCrLf & vbCrLf)
netStream.Write(sendBytes, 0, sendBytes.Length)
'Get the response from webrelay
Dim bytes(tcpClient.ReceiveBufferSize) As Byte
netStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
'Parse the response and update the webrelay state and input text boxes
Dim returndata As String = Encoding.ASCII.GetString(bytes)
'Parse out the relay state and input state
Dim array1 As Char() = returndata.ToCharArray()
Dim ana(4) As Integer
'Relay State found at index 66
If array1(66) = "1" Then
RelayState.Text = "ON"
Else
RelayState.Text = "OFF"
End If
'Input State found at index 94
If array1(94) = "1" Then
inputState.Text = "ON"
Else
inputState.Text = "OFF"
End If
End If
'Close the connection
tcpClient.Close()
End If
Catch ex As Exception
inputState.Text = "Error"
RelayState.Text = "Error"
'Disable the timer
TimerRelayRefresh.Enabled = False
End Try
End Sub
Private Sub sendRequest(ByVal val As String)
Dim tcpClient As New TcpClient()
Dim port As Integer
Try
'Disable the timer
TimerRelayRefresh.Enabled = False
port = Convert.ToInt32(txtPort.Text)
tcpClient.Connect(txt_IPAddress.Text, port)
If tcpClient.Connected Then
MsgBox("connection successful")
'Create a network stream object
Dim netStream As NetworkStream = tcpClient.GetStream()
'If we can read and write to the stream then do so
If netStream.CanWrite And netStream.CanRead Then
'Send the on command to webrelay
Dim sendBytes As Byte() = Encoding.ASCII.GetBytes("GET /state.xml?relayState=1 HTTP/1.1<CR><LF>" & vbCrLf & "Authorization: Basic bm9uZTp3ZWJyZWxheQ==<CR><LF><CR><LF>" & vbCrLf & vbCrLf)
netStream.Write(sendBytes, 0, sendBytes.Length)
'Get the response from webrelay
Dim bytes(tcpClient.ReceiveBufferSize) As Byte
netStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
'Parse the response and update the webrelay state and input text boxes
Dim returndata As String = Encoding.ASCII.GetString(bytes)
'Parse out the relay state and input state
Dim array1 As Char() = returndata.ToCharArray()
'Relay State found at index 66
If array1(66) = "1" Then
RelayState.Text = "ON"
Else
RelayState.Text = "OFF"
End If
'Input State found at index 94
If array1(94) = "1" Then
inputState.Text = "ON"
End If
Else
inputState.Text = "OFF"
End If
End If
'Enable the timer
TimerRelayRefresh.Enabled = True
Catch ex As Exception
inputState.Text = "Error"
RelayState.Text = "Error"
'Disable the timer
TimerRelayRefresh.Enabled = False
End Try
End Sub
Private Sub btn_ControlsX317_On_Click(sender As Object, e As EventArgs) Handles btn_ControlsX317_On.Click
sendRequest("1")
End Sub
Private Sub btn_ControlsX317_Off_Click(sender As Object, e As EventArgs) Handles btn_ControlsX317_Off.Click
sendRequest("0")
End Sub
Private Sub btn_ControlsX317_PULSE_Click(sender As Object, e As EventArgs) Handles btn_ControlsX317_PULSE.Click
sendRequest("2")
End Sub
'End Conetion
'_________________________________________________________________________________________________________________________________________________________________________
End Class

Save/Load BackgroundWorker Progress in vb.net

I am creating a file downloader using backgroundworker & i want to save the progress of backgroundworker so that when i restart the application, on resume, it start the download where i closed last time.
Any help ?
Here is My code for Downloader
Public Class cls_FileDownloader
Dim FileSave As String
Delegate Sub DownloadFIlesafe(ByVal Cancelled As Boolean)
Delegate Sub ChangeTextsSafe(ByVal length As Long, ByVal position As Double, ByVal percent As Long, ByVal speed As Long)
Private Sub cls_FileDownloader_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Text = ""
btn_Cancel.Enabled = False
End Sub
Private Sub btn_Download_Click(sender As Object, e As EventArgs) Handles btn_Download.Click
If Me.txt_Url.Text <> "" Then
Me.SaveFile.FileName = txt_Url.Text.Split("\"c)(txt_Url.Text.Split("\"c).Length - 1)
If SaveFile.ShowDialog = System.Windows.Forms.DialogResult.OK Then
FileSave = SaveFile.FileName
SaveFile.FileName = ""
lbl_SaveTO.Text = "Save To:" & FileSave
txt_Url.Enabled = False
btn_Download.Enabled = False
btn_Cancel.Enabled = True
bg_Worker.RunWorkerAsync()
End If
Else
MessageBox.Show("Please Insert valid file path", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
End Sub
Private Sub bg_Worker_DoWork(sender As Object, e As DoWorkEventArgs) Handles bg_Worker.DoWork
Dim response As FileWebResponse
Dim request As FileWebRequest
Try
request = WebRequest.Create(txt_Url.Text)
response = request.GetResponse
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Dim cancelDelegate As New DownloadFIlesafe(AddressOf Download_Complete)
Me.Invoke(cancelDelegate, True)
Exit Sub
End Try
Dim length As Long = response.ContentLength
Dim safedelegate As New ChangeTextsSafe(AddressOf ChangeTexts)
Me.Invoke(safedelegate, length, 0, 0, 0)
Dim writeStream As New IO.FileStream(Me.FileSave, IO.FileMode.Create)
Dim nRead As Double
'To calculate the download speed
Dim speedtimer As New Stopwatch
Dim currentspeed As Long = -1
Dim readings As Integer = 0
Do
If bg_Worker.CancellationPending Then 'If user abort download
Exit Do
End If
speedtimer.Start()
Dim readBytes(4095) As Byte
Dim bytesread As Long = response.GetResponseStream.Read(readBytes, 0, 4096)
nRead += bytesread
Dim percent As Long = (nRead * 100) / length
Me.Invoke(safedelegate, length, nRead, percent, currentspeed)
If bytesread = 0 Then Exit Do
writeStream.Write(readBytes, 0, bytesread)
speedtimer.Stop()
readings += 1
If readings >= 5 Then 'For increase precision, the speed it's calculated only every five cicles
currentspeed = 20480 / (speedtimer.ElapsedMilliseconds / 1000)
speedtimer.Reset()
readings = 0
End If
Loop
'Close the streams
response.GetResponseStream.Close()
writeStream.Close()
If Me.bg_Worker.CancellationPending Then
IO.File.Delete(Me.FileSave)
Dim cancelDelegate As New DownloadFIlesafe(AddressOf Download_Complete)
Me.Invoke(cancelDelegate, True)
Exit Sub
End If
Dim completeDelegate As New DownloadFIlesafe(AddressOf Download_Complete)
Me.Invoke(completeDelegate, False)
End Sub

FOR statement conflicting with IF statement in VB

I am creating a fairly simple ping tool which shows in milliseconds how long the server took to respond. If the server does not respond, it shows as it responded in 0ms. I wanted to implement an If statement to write Server failed to respond in the ListBox rather than it replied in 0ms. The only problem with this is I have a chunk of code which need to be run outside the If but continues inside the If and involves using the line of code Next... This seems to cause the If statement to not recognise the End If and the End If to not recognise the If...
Here is my code:
For i As Integer = 0 To numberOfPings - 1
Dim ping As New Ping
Dim pingRe As PingReply = ping.Send(pingTarget)
If pingRe.RoundtripTime = 0 Then
Me.listboxPing.Items.Add("Server failed to respond...")
Else
Me.listboxPing.Items.Add("Response from " & pingTarget & " in " & pingRe.RoundtripTime.ToString() & "ms")
listboxPing.SelectedIndex = listboxPing.Items.Count - 1
listboxPing.SelectedIndex = -1
Application.DoEvents()
Threading.Thread.Sleep(500)
Next
Me.listboxPing.Items.Add("")
End If
Does anyone know of a way I could fix this/get around this issue?
Thanks,
If I were going to write code to ping an address and show the results it would look something like this.
Dim pingThrd As Threading.Thread
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If pingThrd Is Nothing OrElse pingThrd.ThreadState = Threading.ThreadState.Stopped Then
RichTextBox1.Clear()
pingThrd = New Threading.Thread(AddressOf PingIt)
pingThrd.IsBackground = True
pingThrd.Start("192.168.33.1")
End If
End Sub
Public Sub PingIt(pingTarget As Object)
Dim numberOfPings As Integer = 5
Dim pingT As String = DirectCast(pingTarget, String)
Dim pingTimeOut As Integer = 1000
Const dlyBetweenPing As Integer = 500
Dim dspStr As String
For i As Integer = 0 To numberOfPings - 1
Dim pingit As New Ping
Dim pingRe As PingReply = pingit.Send(pingT, pingTimeOut)
'check if success
If pingRe.Status = IPStatus.Success Then
dspStr = String.Format("Response from: {0} in {1}ms.", pingRe.Address, pingRe.RoundtripTime)
Else
dspStr = String.Format("{0} failed. Status: {1}", pingRe.Address, pingRe.Status)
End If
Me.BeginInvoke(Sub()
RichTextBox1.AppendText(dspStr)
RichTextBox1.AppendText(Environment.NewLine)
End Sub)
Threading.Thread.Sleep(dlyBetweenPing)
Next
End Sub
edit: Same basic code but allow thread to start with different address and count.
Structure PingWhat
Dim addr As String
Dim howmany As Integer
End Structure
Dim pingThrd As Threading.Thread
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If pingThrd Is Nothing OrElse pingThrd.ThreadState = Threading.ThreadState.Stopped Then
RichTextBox1.Clear()
'setup a thread to do the actual ping'ing
'this allows the UI to function
pingThrd = New Threading.Thread(AddressOf PingIt)
pingThrd.IsBackground = True
'setup address to ping and howmany times to ping it
Dim somePing As New PingWhat With {.addr = "192.168.33.1", .howmany = 3}
'start the thread
pingThrd.Start(somePing)
End If
End Sub
Public Sub PingIt(pingTarget As Object)
Dim pingT As PingWhat = DirectCast(pingTarget, PingWhat)
Dim pingTimeOut As Integer = 1000
Const dlyBetweenPing As Integer = 500
Dim dspStr As String
For i As Integer = 1 To pingT.howmany
Dim pingit As New Ping
Dim pingRe As PingReply = pingit.Send(pingT.addr, pingTimeOut)
'check if success
If pingRe.Status = IPStatus.Success Then
dspStr = String.Format("Response from: {0} in {1} ms.", pingRe.Address, pingRe.RoundtripTime)
Else
dspStr = String.Format("Ping Failed {0}. Status: {1}", pingT.addr, pingRe.Status)
End If
'update the UI
Me.BeginInvoke(Sub()
RichTextBox1.AppendText(dspStr)
RichTextBox1.AppendText(Environment.NewLine)
RichTextBox1.ScrollToCaret()
End Sub)
Threading.Thread.Sleep(dlyBetweenPing)
Next
Me.BeginInvoke(Sub()
RichTextBox1.AppendText("Done")
RichTextBox1.AppendText(Environment.NewLine)
RichTextBox1.ScrollToCaret()
End Sub)
End Sub
Is this what you're after?
For i As Integer = 0 To numberOfPings - 1
Dim ping As New Ping
Dim pingRe As PingReply = ping.Send(pingTarget)
If pingRe.RoundtripTime = 0 Then
Me.listboxPing.Items.Add("Server failed to respond...")
Else
Me.listboxPing.Items.Add("Response from " & pingTarget & " in " & pingRe.RoundtripTime.ToString() & "ms")
listboxPing.SelectedIndex = listboxPing.Items.Count - 1
listboxPing.SelectedIndex = -1
Application.DoEvents()
Threading.Thread.Sleep(500)
add = True
Exit For
End If
Next
If add Then Me.listboxPing.Items.Add("")
The If will change the scope, therefore, you need to use a variable to check whether it went into the Else part.
Of course, you need to close the first If before the Next.
#dbasnett This was the code I using before and it was absolutely perfect for what i needed EXCEPT if a ping failed it would just say (PingTarget) responded in 0ms which is not ideal. Ideally i would like it to say Server failed to respond... . Do you know a way in which this can be achieved by modifying my original code?
Imports System.Net.NetworkInformation
Imports System.Runtime.InteropServices
Public Class PingClient
Private Const EM_SETCUEBANNER As Integer = &H1501
<DllImport("user32.dll", CharSet:=CharSet.Auto)>
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As Integer, <MarshalAs(UnmanagedType.LPWStr)> ByVal lParam As String) As Int32
End Function
Private Sub SetCueText(ByVal control As Control, ByVal text As String)
SendMessage(control.Handle, EM_SETCUEBANNER, 0, text)
End Sub
Private Sub PingClient_Load(sender As Object, e As EventArgs) Handles MyBase.Load
SetCueText(textboxIP, "IP Address/Domain")
SetCueText(textboxPing, "No. Of Pings")
End Sub
Structure PingWhat
Dim addr As String
Dim howmany As Integer
End Structure
Dim pingThrd As Threading.Thread
Public Sub buttonPing_Click(sender As Object, e As EventArgs) Handles buttonPing.Click
If pingThrd Is Nothing OrElse pingThrd.ThreadState = Threading.ThreadState.Stopped Then
Dim pingTarget As String = ""
Dim numberOfPings As Integer = 0
Dim intTimeout As Integer = 2000
If String.IsNullOrEmpty(textboxIP.Text) Then
MsgBox("You must enter an IP Address or Domain.")
Exit Sub
End If
If Not Int32.TryParse(textboxPing.Text, numberOfPings) Then
MsgBox("You must enter a number of how many times the target address will be pinged.")
Exit Sub
End If
If numberOfPings = 0 Then
MsgBox("You must enter a value over 0.")
textboxPing.Clear()
Exit Sub
End If
'setup a thread to do the actual ping'ing
'this allows the UI to function
pingThrd = New Threading.Thread(AddressOf PingIt)
pingThrd.IsBackground = True
'setup address to ping and howmany times to ping it
Dim somePing As New PingWhat With {.addr = pingTarget, .howmany = numberOfPings}
'start the thread
pingThrd.Start(somePing)
End If
Me.listboxPing.Items.Add("")
End Sub
Public Sub PingIt(pingTarget As Object)
Dim pingT As PingWhat = DirectCast(pingTarget, PingWhat)
Dim pingTimeOut As Integer = 1000
Const dlyBetweenPing As Integer = 500
Dim dspStr As String
For i As Integer = 1 To pingT.howmany
Dim pingit As New Ping
Dim pingRe As PingReply = pingit.Send(pingT.addr, pingTimeOut)
'check if success
If pingRe.Status = IPStatus.Success Then
dspStr = String.Format("Response from: {0} in {1} ms.", pingRe.Address, pingRe.RoundtripTime)
Else
dspStr = String.Format("Ping Failed {0}. Status: {1}", pingT.addr, pingRe.Status)
End If
'update the UI
Me.BeginInvoke(Sub()
listboxPing.Items.Add(dspStr)
End Sub)
Threading.Thread.Sleep(dlyBetweenPing)
Next
Me.BeginInvoke(Sub()
listboxPing.Items.Add("Done")
End Sub)
End Sub
Private Sub PingClient_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
Dim Response As Integer
Response = MsgBox("Are you sure you want to exit the Ping Tool?", 36)
If Response = MsgBoxResult.Yes Then
Else
e.Cancel = True
End If
End Sub
End Class