I want to send a message to the hotmail mail and test the mail whether it exists or not. If it does not exist, a message appears for me. A code was made and tested on the gmail mail and it works great, but when converting it to hotmail it did not work. Please help
Private Function GetResponseCode(ByVal ResponseString As String) As Integer
Try
Return Integer.Parse(ResponseString.Substring(0, 3))
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For i = 0 To ListBox1.Items.Count - 1
Dim tClient As TcpClient = New TcpClient("smtp-mail.outlook.com", 587)
Dim CRLF As String = vbCrLf
Dim dataBuffer As Byte()
Dim ResponseString As String
Dim netStream As NetworkStream = tClient.GetStream()
Dim reader As StreamReader = New StreamReader(netStream)
ResponseString = reader.ReadLine()
dataBuffer = BytesFromString("HELO" & CRLF)
netStream.Write(dataBuffer, 0, dataBuffer.Length)
ResponseString = reader.ReadLine()
dataBuffer = BytesFromString("MAIL FROM:<fx121#gmail.com>" & CRLF)
netStream.Write(dataBuffer, 0, dataBuffer.Length)
ResponseString = reader.ReadLine()
dataBuffer = BytesFromString("RCPT TO:<" & Itm(i) + "#hotmail.com" & ">" & CRLF)
netStream.Write(dataBuffer, 0, dataBuffer.Length)
ResponseString = reader.ReadLine()
If GetResponseCode(ResponseString) = 550 Then
MsgBox("Not exist")
Else
MsgBox("exist")
End If
dataBuffer = BytesFromString("QUITE" & CRLF)
netStream.Write(dataBuffer, 0, dataBuffer.Length)
tClient.Close()
Next
End Sub
Related
My code is below
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
For i = 0 To RichTextBox1.Lines.Count - 1
Dim MessageThread As New System.Threading.Thread(AddressOf Checkpath)
MessageThread.Start(i)
Next
End Sub
Public Sub Checkpath(ByVal i As Integer)
Dim url As String
Try
url = RichTextBox1.Lines(i).ToString
Dim req As HttpWebRequest = DirectCast(HttpWebRequest.Create(url), HttpWebRequest)
Dim response As HttpWebResponse
Dim resUri As String
response = req.GetResponse
resUri = response.ResponseUri.AbsoluteUri
RichTextBox2.AppendText(resUri & vbNewLine)
Catch ex As Exception
unexpected += 1
MsgBox(ex.ToString)
Label6.Text = "Unexpected: " & unexpected
End Try
End Sub
When ever i do this i get error that
Richtextbox i is array outside of bound
but if i use msgbox(i) before the code,
Public Sub Checkpath(ByVal i As Integer)
MsgBox(i)
Dim url As String
Try
url = RichTextBox1.Lines(i).ToString
Dim req As HttpWebRequest = DirectCast(HttpWebRequest.Create(url), HttpWebRequest)
Dim response As HttpWebResponse
Dim resUri As String
response = req.GetResponse
resUri = response.ResponseUri.AbsoluteUri
RichTextBox2.AppendText(resUri & vbNewLine)
Catch ex As Exception
unexpected += 1
MsgBox(ex.ToString)
Label6.Text = "Unexpected: " & unexpected
End Try
End Sub
works fine or if i do like this
Public Sub Checkpath(ByVal i As Integer)
Dim url As String
Try
MsgBox(i)
url = RichTextBox1.Lines(i).ToString
Dim req As HttpWebRequest = DirectCast(HttpWebRequest.Create(url), HttpWebRequest)
Dim response As HttpWebResponse
Dim resUri As String
response = req.GetResponse
resUri = response.ResponseUri.AbsoluteUri
RichTextBox2.AppendText(resUri & vbNewLine)
Catch ex As Exception
unexpected += 1
MsgBox(ex.ToString)
Label6.Text = "Unexpected: " & unexpected
End Try
End Sub
it works fine but i don't want to display the msgbox
any solution without the msgbox thing?
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
I've got a front facing ASPX page that displays several buttons and preforms the code requested. The issue is that I'm reading a relay and so my current state of the web relay is always behind due to my page refresh so I'm thinking I just need to start at the Page_Load event to make this happen correctly and regenerate the status of the relay.
My question is, how do I call the Page_Load() from within the button Click sub?
'Global Gate Interface
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim tcpClient As New TcpClient()
'Connect to webrelay
tcpClient.Connect("xx.xx.xx.xx", 80)
'Create a network stream object
Dim netStream As NetworkStream = tcpClient.GetStream()
'Create the XML command to send to Webrelay
Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes("GET /state.xml HTTP/1.1" & vbCrLf & "Authorization: Basic bm9uZTp3ZWJyZWxheQ==" & vbCrLf & vbCrLf)
'Send the command to webrelay
netStream.Write(sendBytes, 0, sendBytes.Length)
'Get the response from webrelay
Dim bytes(tcpClient.ReceiveBufferSize) As Byte
netStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
'Convert the bytes received from Webrelay into a string
Dim returndata As String = Encoding.ASCII.GetString(bytes)
'Convert the string into and array
Dim array1 As Char() = returndata.ToCharArray()
'Relay State found at index 66 of array
If array1(66) = "1" Then
relayState.Text = "ON"
Else
relayState.Text = "OFF"
End If
'Input State found at index 94 of array
If array1(94) = "1" Then
inputState.Text = "ON"
Else
inputState.Text = "OFF"
End If
'Close the connection
tcpClient.Close()
End Sub
'Turn East relay On
Protected Sub relayOnEast_Click(sender As Object, e As EventArgs) Handles eastOpen.Click
Dim tcpClient As New TcpClient()
'Connect to webrelay
tcpClient.Connect("xx.xx.xx.xx", 80)
'Create a network stream object
Dim netStream As NetworkStream = tcpClient.GetStream()
'Create the XML command to send 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)
'Send the command to webrelay
netStream.Write(sendBytes, 0, sendBytes.Length)
'Close the connection
tcpClient.Close()
'RERUN PAGE LOAD HERE?
End Sub
Just move the code from Page_Load() to a separate private method and call that method in Page_Load() and relayOnEast_Click().
Side note: this might not work as you have to pay attention to the life cycle of a ASPX page.
Put the code that is inside the protected sub into a separate sub maybe like this
and then call the new sub from the form load event. And then you can call the same code from your other sub.
Protected sub PageReload
Dim tcpClient As New TcpClient()
'Connect to webrelay
tcpClient.Connect("xx.xx.xx.xx", 80)
'Create a network stream object
Dim netStream As NetworkStream = tcpClient.GetStream()
'Create the XML command to send to Webrelay
Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes("GET /state.xml HTTP/1.1" & vbCrLf & "Authorization: Basic bm9uZTp3ZWJyZWxheQ==" & vbCrLf & vbCrLf)
'Send the command to webrelay
netStream.Write(sendBytes, 0, sendBytes.Length)
'Get the response from webrelay
Dim bytes(tcpClient.ReceiveBufferSize) As Byte
netStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
'Convert the bytes received from Webrelay into a string
Dim returndata As String = Encoding.ASCII.GetString(bytes)
'Convert the string into and array
Dim array1 As Char() = returndata.ToCharArray()
'Relay State found at index 66 of array
If array1(66) = "1" Then
relayState.Text = "ON"
Else
relayState.Text = "OFF"
End If
'Input State found at index 94 of array
If array1(94) = "1" Then
inputState.Text = "ON"
Else
inputState.Text = "OFF"
End If
'Close the connection
tcpClient.Close()
End Sub
So I've finally got this to almost work but now every few times I test the process the form and the progressbar freeze. I'm also sure there are much more efficient ways of doing this so any constructive criticism would be greatly appreciated.
This is the coding for one page of a program that allows the user to click one button to download and install one application and then press the next button to download and install a different application:
Imports System.Net.WebRequestMethods
Public Class Software
'Open link in external browser
Public Sub HandleRequestNavigate(ByVal sender As Object, ByVal e As RequestNavigateEventArgs)
Process.Start(New ProcessStartInfo(e.Uri.AbsoluteUri))
e.Handled = True
End Sub
'Declarations
Shared progressamc As New Progress
Shared progresscti As New ProgressCTI
WithEvents startcti As New Process
WithEvents startamc As New Process
WithEvents startsfstb As New Process
WithEvents amcworker As New ComponentModel.BackgroundWorker
WithEvents ctiworker As New ComponentModel.BackgroundWorker
Dim ProgressBarAMC As Object = Progress.ProgressBar1
Dim blprgrsAMC As Object = Progress.blprgrs
Dim ProgressBarCTI As Object = progresscti.ProgressBar1
Dim blprgrsCTI As Object = progresscti.blprgrs
'FTP Values
Const host As String = "ftp://10.167.16.80/"
Const username As String = "anonymous"
Const password As String = ""
'AMC File Put/Get
Const localfileamc As String = "C:\AMC.exe"
Const Remotefileamc As String = "Bin/AMC.exe"
'CTI File Put/Get
Const localfilecti As String = "C:\CTI.exe"
Const Remotefilecti As String = "Bin/CTI.exe"
'On Init
Public Sub New()
InitializeComponent()
amcworker.WorkerReportsProgress = True
amcworker.WorkerSupportsCancellation = True
ctiworker.WorkerReportsProgress = True
ctiworker.WorkerSupportsCancellation = True
End Sub
'Install AMC Button
Private Sub ButtonAMC(sender As Object, e As RoutedEventArgs)
Dim butt1 As Button = DirectCast(sender, Button)
butt1.IsEnabled = False
Dispatcher.BeginInvoke(New Action(AddressOf progressamc_Show))
AddHandler Progress.Cancel_Click, AddressOf myProcessamc_Exited
amcworker.RunWorkerAsync()
End Sub
'Open Dialog
Private Sub progressamc_Show()
Try
progressamc.ShowDialog()
Catch ex As Exception
MessageBox.Show("An error has occurred during the process:" & vbCrLf & vbCrLf & ex.Message & vbCrLf & vbCrLf & "Please close the application and try again." _
& vbCrLf & "If you continue to encounter this error please Email")
End Try
End Sub
'FTP - Download
Private Sub ftpseshamc_DoWork(ByVal sender As System.Object, ByVal e As ComponentModel.DoWorkEventArgs) Handles amcworker.DoWork
Dim URI As String = host & Remotefileamc
Dim FTP As System.Net.FtpWebRequest = CType(System.Net.FtpWebRequest.Create(URI), System.Net.FtpWebRequest)
'Set the credentials
FTP.Credentials = New System.Net.NetworkCredential(username, password)
'FTP Options
FTP.KeepAlive = False
FTP.UseBinary = True
'Define the action as Download
FTP.Method = System.Net.WebRequestMethods.Ftp.DownloadFile
'Get the response to the Ftp request and the associated stream
Try
Dim response As System.Net.FtpWebResponse = CType(FTP.GetResponse, System.Net.FtpWebResponse)
Dim Length As Long = response.ContentLength
Dim StopWatch As New Stopwatch
Dim CurrentSpeed As Double = Nothing
Using responseStream As IO.Stream = response.GetResponseStream
'loop to read & write to file
Using fs As New IO.FileStream(localfileamc, IO.FileMode.Create)
Dim buffer(2047) As Byte
Dim read As Integer = 0
Dim count As Integer
Do
If amcworker.CancellationPending = True Then
e.Cancel = True
Return
End If
StopWatch.Start()
amcworker.ReportProgress(CShort(count / Length * 100 + 0.5))
read = responseStream.Read(buffer, 0, buffer.Length)
fs.Write(buffer, 0, read)
count += read
Loop Until read = 0
StopWatch.Stop()
responseStream.Close()
fs.Flush()
fs.Close()
End Using
responseStream.Close()
End Using
response.Close()
Catch ex As Exception
MessageBox.Show("An error has occurred during the process:" & vbCrLf & vbCrLf & ex.Message & vbCrLf & vbCrLf & "Please close the application and try again." _
& vbCrLf & "If you continue to encounter this error please Email")
myProcessamc_Exited()
End Try
Installamc()
End Sub
'Starts the installation
Sub Installamc()
startamc.StartInfo.FileName = "C:\AMC.exe"
startamc.EnableRaisingEvents = True
Try
startamc.Start()
Catch ex As Exception
MsgBox(ex.Message)
End Try
Dispatcher.Invoke(New Action(AddressOf Progressamc_Hide))
End Sub
'Hide Dialog during install
Private Sub Progressamc_Hide()
progressamc.Hide()
End Sub
'Report progress
Private Sub amcworker_ProgressChanged(ByVal sender As System.Object, ByVal e As ComponentModel.ProgressChangedEventArgs) Handles amcworker.ProgressChanged
ProgressBarAMC.value = e.ProgressPercentage
blprgrsAMC.Content = "Downloading: " & e.ProgressPercentage & "%"
End Sub
End Class
Again, any help would be greatly appreciated.
Edit: I've made the following edit to the code but I'm not entirely sure it's doing what I think it's doing. Basically what I intended is for the ReportProgress to only run once every 2047 bytes read.
'Get the response to the Ftp request and the associated stream
Try
Dim response As System.Net.FtpWebResponse = CType(FTP.GetResponse, System.Net.FtpWebResponse)
Dim Length As Long = response.ContentLength
Dim StopWatch As New Stopwatch
Dim CurrentSpeed As Double = Nothing
Using responseStream As IO.Stream = response.GetResponseStream
'loop to read & write to file
Using fs As New IO.FileStream(localfileamc, IO.FileMode.Create)
Dim buffer(2047) As Byte
Dim read As Integer = 0
Dim count As Integer
Dim chunk As Integer = Int(2047 / Length)
Dim cycle As Integer = chunk = count
Do
If amcworker.CancellationPending = True Then
e.Cancel = True
Return
End If
StopWatch.Start()
If cycle = True Then
amcworker.ReportProgress(CShort(count / Length * 100 + 0.5))
Else
End
End If
read = responseStream.Read(buffer, 0, buffer.Length)
fs.Write(buffer, 0, read)
count += read
Loop Until read = 0
StopWatch.Stop()
responseStream.Close()
fs.Flush()
fs.Close()
End Using
responseStream.Close()
End Using
response.Close()
Catch ex As Exception
MessageBox.Show("An error has occurred during the process:" & vbCrLf & vbCrLf & ex.Message & vbCrLf & vbCrLf & "Please close the application and try again." _
& vbCrLf & "If you continue to encounter this error please Email")
myProcessamc_Exited()
End Try
I didn't scrutinize the code carefully, but I don't see why you're using stopwatch, so I took out the references. I'm not sure what starting it multiple times inside the loop and ending it outside would do anyway.
The use of the word END in the second example will comletely end your app! Pretty sure that's what you want there.
Try this modification of your first code. The key is only updating if change is >= 5%:
Using fs As New IO.FileStream(localfileamc, IO.FileMode.Create)
Dim buffer(2047) As Byte
Dim read As Integer = 0
Dim count As Integer
dim LastPct as Short = -5
dim Pct as Short = 0
Do
If amcworker.CancellationPending = True Then
e.Cancel = True
Return
End If
Pct = CShort(count / Length * 100 + 0.5)
if Pct>= (LastPct + 5)
amcworker.ReportProgress(Pct)
LastPCT= Pct
EndIf
read = responseStream.Read(buffer, 0, buffer.Length)
fs.Write(buffer, 0, read)
count += read
Loop Until read = 0
amcworker.ReportProgress(100)
responseStream.Close()
fs.Flush()
fs.Close()
End Using
I'm trying to save a binary file stored in a SQL database with a SaveDialog, the function RetrieveFile retrieves the specified file from the database as a Byte array, here's what I have so far:
Private Shared Function RetrieveFile(ByVal filename As String) As Byte()
Dim connection As New SqlConnection("Data Source=SERVER\SQL2008;Initial Catalog=NorthPole;Integrated Security=True")
Dim command As New SqlCommand("SELECT pcfFile FROM Items WHERE pcfFileName=#Filename", connection)
command.Parameters.AddWithValue("#Filename", filename)
connection.Open()
Dim reader As SqlDataReader = command.ExecuteReader(System.Data.CommandBehavior.SequentialAccess)
reader.Read()
Dim memory As New MemoryStream()
Dim startIndex As Long = 0
Const ChunkSize As Integer = 256
While True
Dim buffer As Byte() = New Byte(ChunkSize - 1) {}
Dim retrievedBytes As Long = reader.GetBytes(1, startIndex, buffer, 0, ChunkSize)
memory.Write(buffer, 0, CInt(retrievedBytes))
startIndex += retrievedBytes
If retrievedBytes <> ChunkSize Then
Exit While
End If
End While
connection.Close()
Dim data As Byte() = memory.ToArray()
memory.Dispose()
Return data
End Function
Private Sub SaveAsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveAsToolStripMenuItem.Click
Dim saveFileDialog1 As New SaveFileDialog()
saveFileDialog1.Filter = "PCF File|*.pcf|"
saveFileDialog1.Title = "Save an pcf File"
saveFileDialog1.ShowDialog()
If saveFileDialog1.FileName <> "" Then
Dim fs As System.IO.FileStream = CType(RetrieveFile("FakePCF.pcf"), System.IO.FileStream)
fs.Close()
End If
End Sub
Files are saved as "SqlDbType.VarBinary" within the database.
I get: "Index was outside the bounds of the array." on:
Dim retrievedBytes As Long = reader.GetBytes(1, startIndex, buffer, 0, ChunkSize)
The MemoryStream appears to not be retrieving the data yet the SQL sytax is correct.
What am I doing wrong?
Well, first of all, your method returns byte[] and you're trying to cast it to FileStream. You should change your handler to following:
Private Sub SaveAsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveAsToolStripMenuItem.Click
Dim saveFileDialog1 As New SaveFileDialog()
saveFileDialog1.Filter = "PCF File|*.pcf|"
saveFileDialog1.Title = "Save an pcf File"
saveFileDialog1.ShowDialog()
If saveFileDialog1.FileName <> "" Then
Dim fs As New System.IO.FileStream (saveFileDialog1.FileName, System.IO.FileMode.Create, System.IO.FileAccess.Write)
Dim data As Byte() = RetrieveFile("FakePCF.pcf")
fs.Write(data, 0, data.Length)
fs.Flush()
fs.Close()
End If
End Sub