ObjectDisposedException was unhandled when closing form using System.Net.Mail namespace - vb.net

This is the error I'm getting when Me.Close() is called:
This is my code:
Imports System.Net.Mail
Imports System.IO
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
Dim mail As New MailMessage()
Dim SmtpServer As New SmtpClient("smtp.gmail.com")
mail.From = New MailAddress("your email#domain.com")
mail.[To].Add("to#domain.com")
mail.Subject = "Trial"
mail.Body = "Trial"
Dim path As String = "C:\Users\CrystalUser\Desktop\trial"
Dim dir As New DirectoryInfo(path)
Dim filesInDirectory As FileInfo() = dir.GetFiles()
Dim attach As System.Net.Mail.Attachment
For Each file In filesInDirectory
attach = New System.Net.Mail.Attachment(file.FullName)
mail.Attachments.Add(attach)
Next
SmtpServer.Port = 587
SmtpServer.Credentials = New System.Net.NetworkCredential("username", "password")
SmtpServer.EnableSsl = True
SmtpServer.Send(mail)
MsgBox("Sent Successfuly", MsgBoxStyle.Information, "Send")
Catch alvin As Exception
MessageBox.Show(alvin.Message)
End Try
Me.Close()
End Sub
End Class
I want the program to close automatically after sending the MailMessage.
I have used Me.Hide() and Me.Close() but neither worked.

Although your error is little unclear and this answer may not fix your problem it would be wise to implement Using on the MailMessage, SmtpClient and Attachment classes:
Sometimes your code requires an unmanaged resource, such as a file handle, a COM wrapper, or a SQL connection. A Using block guarantees the disposal of one or more such resources when your code is finished with them. This makes them available for other code to use.
I would also look at reducing some unnecessary code when using .GetFiles().
Code:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
Using mail As New MailMessage("your email#domain.com", "to#domain.com", "Trial", "Trial"),
smtpServer As New SmtpClient("smtp.gmail.com", 587)
Dim filesInDirectory As FileInfo() = New DirectoryInfo("C:\Users\CrystalUser\Desktop\trial").GetFiles()
For Each file In filesInDirectory
Using attach As New Attachment(file.FullName)
mail.Attachments.Add(attach)
End Using
Next
smtpServer.Credentials = New System.Net.NetworkCredential("username", "password")
smtpServer.EnableSsl = True
smtpServer.Send(mail)
MessageBox.Show("Mail sent")
End Using
Catch alvin As Exception
MessageBox.Show(alvin.Message)
End Try
Me.Close()
End Sub
The point of implementing Using is so that the objects are disposed of properly once finished with. The objects will also be disposed of before entering the Catch statement, should any errors occur.
Give this a go and let me know how you get on.

Related

No value given for one or more required parameters while trying to access a picture file from an Acces database using VB.net

Im doing a school project. and I was testing a login form for my app. I'm trying separately from my login form and a profile pic form. I have successfully managed to save the image to the access database but I have had quite a few problems trying to display it on a textbox on my form.
This is the whole app code:
Imports System.Data.OleDb
Imports System.IO
Public Class Form2
Dim con As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\geral\source\repos\BD de imagenes\BD de imagenes\DBImagenes.mdb")
Dim cmd As New OleDbCommand
Dim sql As String
Dim da As New OleDb.OleDbDataAdapter
Dim result As Integer
Private Sub saveimage(sql As String)
Try
Dim arrimage() As Byte
Dim mstream As New System.IO.MemoryStream
PictureBox1.Image.Save(mstream, System.Drawing.Imaging.ImageFormat.Png)
arrimage = mstream.GetBuffer()
Dim Filesize As UInt32
Filesize = mstream.Length
mstream.Close()
con.Open()
cmd = New OleDbCommand
With cmd
.Connection = con
.CommandText = sql
.Parameters.AddWithValue("#Imagen", arrimage)
.Parameters.Add("#Nombre", OleDbType.VarChar).Value = TextBox1.Text
.ExecuteNonQuery()
End With
Catch ex As Exception
MsgBox(ex.Message)
Finally
con.Close()
End Try
End Sub
'End Try
Public conex As New OleDbConnection()
Public Sub conexion()
conex.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\geral\source\repos\BD de imagenes\BD de imagenes\DBImagenes.mdb"
conex.Open()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles BTNGuardar.Click
sql = "Insert into TBImg (Imagen, Nombre) Values (#Imagen, #Nombre)"
'sql = "Insert into TBImg (Imagen) Values (#Imagen)"
saveimage(sql)
MsgBox("Image has been saved in the database")
End Sub
Private Sub BtnExaminar_Click(sender As Object, e As EventArgs) Handles BtnExaminar.Click
OpenFileDialog1.Filter = "Imagenes JPG|*.jpg|Imagenes PNG|*.png"
OpenFileDialog1.RestoreDirectory = True
If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
PictureBox1.Image = Image.FromFile(OpenFileDialog1.FileName)
End If
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
End Sub
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
Try
With OpenFileDialog1
'CHECK THE SELECTED FILE IF IT EXIST OTHERWISE THE DIALOG BOX WILL DISPLAY A WARNING.
.CheckFileExists = True
'CHECK THE SELECTED PATH IF IT EXIST OTHERWISE THE DIALOG BOX WILL DISPLAY A WARNING.
.CheckPathExists = True
'GET AND SET THE DEFAULT EXTENSION
.DefaultExt = "jpg"
'RETURN THE FILE LINKED TO THE LNK FILE
.DereferenceLinks = True
'SET THE FILE NAME TO EMPTY
.FileName = ""
'FILTERING THE FILES
.Filter = "(*.jpg)|*.jpg|(*.png)|*.png|(*.jpg)|*.jpg|All files|*.*"
'SET THIS FOR ONE FILE SELECTION ONLY.
.Multiselect = False
'SET THIS TO PUT THE CURRENT FOLDER BACK TO WHERE IT HAS STARTED.
.RestoreDirectory = True
'SET THE TITLE OF THE DIALOG BOX.
.Title = "Select a file to open"
'ACCEPT ONLY THE VALID WIN32 FILE NAMES.
.ValidateNames = True
If .ShowDialog = DialogResult.OK Then
Try
PictureBox1.Image = Image.FromFile(OpenFileDialog1.FileName)
Catch fileException As Exception
Throw fileException
End Try
End If
End With
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Exclamation, Me.Text)
End Try
End Sub
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
conexion()
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End Sub
Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click
End Sub
Private Sub BtnBuscar_Click(sender As Object, e As EventArgs) Handles BtnBuscar.Click
Dim arrimage() As Byte
Dim conn As New OleDb.OleDbConnection
Dim Myconnection As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\geral\source\repos\BD de imagenes\BD de imagenes\DBImagenes.mdb"
conn.ConnectionString = Myconnection
conn.Open()
sql = "Select * from TBImg where Nombre=" & (TBBuscar.Text)
Dim cmd As New OleDbCommand
With cmd
.Connection = conex
.CommandText = sql
End With
Dim publictable As New DataTable
Try
da.SelectCommand = cmd
da.Fill(publictable)
TextBox1.Text = publictable.Rows(1).Item("Nombre").ToString
arrimage = publictable.Rows(1).Item("Imagen")
Dim mstream As New System.IO.MemoryStream(arrimage)
PictureBox1.Image = Image.FromStream(mstream)
Catch ex As Exception
MsgBox(ex.Message)
Finally
da.Dispose()
conn.Close()
End Try
End Sub
End Class
the relevant part is at Private Sub BtnBuscar_Click.
I'm trying to search in a textbox for the name that I saved the image with. but I haven't had success all I get is the error of the title.
this is how my database looks like the images are saved as an ole object
This is the error I get
I was following this tutorial https://www.youtube.com/watch?v=zFdjp39mfhQ
but he didn't quite explain how to use the:
TextBox1.Text = publictable.Rows(0).Item(1)
arrimage = publictable.Rows(0).Item(1)'
don't know if it's the cause of the issue.
instructions. The reason why my code looks different is that I was trying to stuff to see if I could make it work.
I have tried to search for answers and people suggest that I may have put the table name wrong or the column but I copied the name exactly how it is in the table with ctrl + c and ctrl + v.
what I want is that when I type the name in the column name of the database that it brings the designated picture stored as ole object onto my desired picture box on my form app.
Needless to say, I'm not that experienced with vb.net and SQL, Acces. I'm just following tutorials for being able to complete the project.
Do not declare connections or commands or datareaders at the class level. They all need to have their Dispose methods called. Using blocks will have the declare, closing and disposing even if there is an error. Streams also need Using blocks.
Defaults for an OpenFiledialog
Multiselect is False
CheckFileExists is True
CheckPathExists is True
DereferenceLinks is True
ValidateNames is True
FileName is ""
Unless you are getting paid by the line, it is unnecessary to reset these values to their defaults.
I have alerted your Filter to exclude All Files. You also had jpg appearing twice.
I declared a variable to hold the file extension, PictureFormat, of the image file so you could provide the proper parameter for ImageFormat.
When you retrieve the image field from the database it comes as an Object. To get the Byte() a DirectCast should work.
Private PictureFormat As String
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
FillPictureBoxFromFile()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles BTNGuardar.Click
Try
saveimage()
Catch ex As Exception
MessageBox.Show(ex.Message)
Exit Sub
End Try
MsgBox("Image has been saved in the database")
End Sub
Private cnStr As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\geral\source\repos\BD de imagenes\BD de imagenes\DBImagenes.mdb"
Private Sub saveimage()
Dim arrimage() As Byte
Using mstream As New System.IO.MemoryStream
If PictureFormat.ToLower = ".png" Then
PictureBox1.Image.Save(mstream, System.Drawing.Imaging.ImageFormat.Png)
ElseIf PictureFormat.ToLower = ".jpg" Then
PictureBox1.Image.Save(mstream, System.Drawing.Imaging.ImageFormat.Jpeg)
End If
arrimage = mstream.GetBuffer()
Dim Filesize As Long
Filesize = mstream.Length
End Using
Using con As New OleDbConnection(cnStr),
cmd As New OleDbCommand("Insert into TBImg (Imagen, Nombre) Values (#Imagen, #Nombre)", con)
With cmd
.Parameters.Add("#Imagen", OleDbType.Binary).Value = arrimage
.Parameters.Add("#Nombre", OleDbType.VarChar).Value = TextBox1.Text
con.Open()
.ExecuteNonQuery()
End With
End Using
End Sub
Private Sub BtnExaminar_Click(sender As Object, e As EventArgs) Handles BtnExaminar.Click
FillPictureBoxFromFile()
End Sub
Private Sub BtnBuscar_Click(sender As Object, e As EventArgs) Handles BtnBuscar.Click
Dim dt As DataTable
Try
dt = GetDataByName(TBBuscar.Text)
Catch ex As Exception
MessageBox.Show(ex.Message)
Exit Sub
End Try
TextBox1.Text = dt(0)("Nombre").ToString
Dim arrimage = DirectCast(dt(0)("Imagen"), Byte())
Dim mstream As New System.IO.MemoryStream(arrimage)
PictureBox1.Image = Image.FromStream(mstream)
End Sub
Private Function GetDataByName(name As String) As DataTable
Dim dt As New DataTable
Using conn As New OleDb.OleDbConnection(cnStr),
cmd As New OleDbCommand("Select * from TBImg where Nombre= #Buscar", conn)
cmd.Parameters.Add("#Buscar", OleDbType.VarChar).Value = TBBuscar.Text
conn.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
Return dt
End Function
Private Sub FillPictureBoxFromFile()
With OpenFileDialog1
.Filter = "(*.jpg)|*.jpg|(*.png)|*.png"
.RestoreDirectory = True
.Title = "Select a file to open"
If .ShowDialog = DialogResult.OK Then
PictureBox1.Image = Image.FromFile(OpenFileDialog1.FileName)
End If
PictureFormat = Path.GetExtension(OpenFileDialog1.FileName)
End With
End Sub

the cc and bcc is not working i cant send it through one of them

Imports System.Net.Mail
Imports System.IO
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
Dim mail As New MailMessage()
Dim SmtpServer As New SmtpClient(My.Settings.smtpserver)
mail.From = New MailAddress(My.Settings.from)
mail.[To].Add(My.Settings.destination)
mail.Subject = "Program"
mail.Body = "Hi this is a msg form .net application"
Dim path As String = My.Settings.desktop
Dim dir As New DirectoryInfo(path)
Dim filesInDirectory As FileInfo() = dir.GetFiles()
Dim attach As System.Net.Mail.Attachment
For Each file In filesInDirectory
attach = New System.Net.Mail.Attachment(file.FullName)
mail.Attachments.Add(attach)
Next
SmtpServer.Port = My.Settings.port
SmtpServer.Credentials = New
System.Net.NetworkCredential(My.Settings.username, My.Settings.password)
SmtpServer.EnableSsl = True
SmtpServer.Send(mail)
MsgBox("Sent Successfuly!", MsgBoxStyle.Information, "Send!")
mail.CC.Add(My.Settings.CC)
mail.Bcc.Add(My.Settings.BCC)
Catch ex As Exception
MsgBox("Failed Sending Email!", MsgBoxStyle.Critical, "Failed!")
End Try
Application.Exit()
End Sub
End Class
the cc and bcc is not working i cant send through cc nor bcc is there any problem with my codes? the user can use this cc and bcc like gmail.
Well - you are setting CC and BCC after you send the email. Thats your problem. Move the lines:
mail.CC.Add(My.Settings.CC)
mail.Bcc.Add(My.Settings.BCC)
Up to where you are setting Mail.Subject, etc.

Send e-mail through VB.NET using SMTP

I really started to get confused about sending an e-mail to (example: test#test.com) through VB.NET and for sure using SMTP.
I want the mail to be sent when Button1 is clicked (example).
So I started by a code like that
Imports System.Net.Mail
Public Class MyProgram
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using message As New MailMessage()
'set to the from, to and subject fields
message.From = New MailAddress("sender#sender.com")
message.[To].Add(New MailAddress("test#test.com"))
message.Subject = "Test"
'code the message body
Dim MsgBody As String
MsgBody = TextBox1.Text.ToString() & vbCr & _
TextBox2.Text.ToString()
message.Body = MsgBody
Dim client As New SmtpClient()
client.Host = "smtp.example.com"
client.Port = "465"
client.EnableSsl = True
client.Credentials = New Net.NetworkCredential("USERNAME#MAIL.COM", "PASSWORD")
client.Send(message)
End Using
'display submitted box
MessageBox.Show("Congrats", "Congratulations!")
'close form
Me.Close()
End Sub
End Class
And I get:
Next, I tried another code (which is) ...
Imports System.Net.Mail
Public Class MyProgram
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Smtp_Server As New SmtpClient
Dim e_mail As New MailMessage()
Smtp_Server.UseDefaultCredentials = False
Smtp_Server.Credentials = New Net.NetworkCredential("USERNAME#MAIL.COM", "PASSWORD")
Smtp_Server.Port = 465
Smtp_Server.EnableSsl = True
Smtp_Server.Host = "smtp.example.com"
e_mail = New MailMessage()
e_mail.From = New MailAddress("sender#sender.com")
e_mail.To.Add("test#test.com")
e_mail.Subject = "Test E-mail Address Sent by My Program"
e_mail.IsBodyHtml = False
e_mail.Body = "Test"
Smtp_Server.Send(e_mail)
MsgBox("Mail Sent")
End Sub
End Class
And now I get the following in the Debugger:
And at last the e-mail isn't sent!
Please don't say "sender#sender.com" isn't configured as a sender e-mail address because it is!
I really need help!
Thanks. :-)

Send an email on VB.net

Can anyone help me. I've created a email program. I'm having an error when clicking on the send button. Here's my code:
Imports System.Net.Mail
Public Class frmEmail
Dim emailaddress As String
Dim password As String
Dim port As Integer
Dim host As String
Private Sub frmEmail_Load(sender As Object, e As EventArgs)
If emailaddress.ToLower.Contains("#gmail") Then
port = 587
host = "smtp.gmail.com"
ElseIf emailaddress.ToLower.Contains("#yahoo") Then
port = 465
host = "smtp.mail.yahoo.com"
End If
End Sub
Private Sub btnSend_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnSend.Click
Try
Dim smtpServer As New SmtpClient
Dim mail As New MailMessage()
smtpServer.Credentials = New Net.NetworkCredential(emailaddress, password)
smtpServer.Port = port
smtpServer.Host = host
smtpServer.EnableSsl = True
mail = New MailMessage()
mail.From = New MailAddress(emailaddress)
mail.To.Add(txtTo.Text)
mail.Subject = txtSubject.Text
mail.Body = txtMessage.Text
smtpServer.Send(mail)
MsgBox("The mail is send!", MsgBoxStyle.Information)
Catch error_t As Exception
MsgBox(error_t.ToString)
End Try
End Sub
End Class
And I've got this error: System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name:value
at System.Net.Mail.SmtpClient.set_Port(Int32 value)
***Edited forgot to modify it to the original code
Your sub
Private Sub frmEmail_Load(sender As Object, e As EventArgs)
doesnt run when the form loads.
Because of this port is set to the default value of 0
You need to tell VB.Net to run when the form loads like this
Private Sub frmEmail_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Also further on down the code, you might find that you get an error about authentication from the email server. If you get this, just below
Dim smtpServer As New SmtpClient
add this
smtpServer.UseDefaultCredentials = False
it might work.

Cannot connect to Access using VB.net

i want to create a login page for my application. and when everything has finished and i want to login it always shows
Error :
The Microsoft Jet database engine cannot open the file 'C:\Users\Gio\Documents\Visual Studio 2012\Projects\CSS\CSS\bin\Debug'. It is already opened exclusively by another user, or you need permission to view its data.
Code :
Imports System.Data.OleDb
Public Class Login
Dim path = System.Windows.Forms.Application.StartupPath
Private Sub Login_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub loginbtn_Click(sender As Object, e As EventArgs) Handles loginbtn.Click
Dim connection As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Gio\Documents\Visual Studio 2012\Projects\CSS\CSS\bin\Debug;")
Dim command As New OleDbCommand("SELECT [ID] FROM [User] WHERE [usernameField] = Username AND [passwordField] = Password", connection)
Dim usernameparam As New OleDbParameter("Username", Me.usernamebox.Text)
Dim passwordparam As New OleDbParameter("Password", Me.passwordbox.Text)
command.Parameters.Add(usernameparam)
command.Parameters.Add(passwordparam)
command.Connection.Open()
Dim reader As OleDbDataReader = command.ExecuteReader()
If reader.HasRows Then
MessageBox.Show("Login Succesful!")
passwordbox.Text = ""
Me.Hide()
Main.Show()
Else
MessageBox.Show("Username and Password are incorrect!")
passwordbox.Text = ""
End If
command.Connection.Close()
End Sub
Private Sub exitbtn_Click(sender As Object, e As EventArgs) Handles exitbtn.Click
Me.Close()
End Sub
End Class
Change this line
Dim connection As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Gio\Documents\Visual Studio 2012\Projects\CSS\CSS\bin\Debug;")
to
Dim connection As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Gio\Documents\Visual Studio 2012\Projects\CSS\CSS\bin\Debug\YourMSAccessDB.mdb;")
or to load the db in your output directory
Dim connection As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=.\YourMSAccessDB.mdb;")
'".\" is equivalent to your output directory or where your application (exe file) is located.