Check if SMTP is running or failed to send email - vb.net

I am using SMTP server to send emails.
I would like to get an error message when the SMTP server is down or when the email was not delivered.
With DeliveryNotificationOptions.OnFailure I get an email that the email has not been delivered.
I would like to get an error. Is this possible?
How I can check if SMTP is running?
Here is the code I use:
Dim serverName As String = ""
Dim mailSenderInstance As SmtpClient = Nothing
Dim AnEmailMessage As New MailMessage
Dim sendersEmail As String = ""
Try
serverName = GetServerName("EMAIL_SERVER")
mailSenderInstance = New SmtpClient(serverName, 25)
sendersEmail = GetSendersEmail(msUserName)
AnEmailMessage.From = New MailAddress(sendersEmail)
'MAIL DETAILS
AnEmailMessage.Subject = "New Email"
AnEmailMessage.Body = "The Message"
AnEmailMessage.To.Add(anEmailAddress)
' Delivery notifications
AnEmailMessage.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure
mailSenderInstance.UseDefaultCredentials = True 'False
mailSenderInstance.Send(AnEmailMessage)
Catch ex As System.Exception
MessageBox.Show(ex.ToString)
Finally
AnEmailMessage.Dispose()
mailSenderInstance.Dispose()
End Try

add another try catch block around your SMTP declaration
try
mailSenderInstance = New SmtpClient(serverName, 25)
catch ex as exception
msgbox( "Error creating SMTP connection: " & ex.message)
end try
regards

ok, you want to know the SMTP status. SMTP runs as a Service. I've written a function for you to know status of ANY service in the system. Add reference to "System.ServiceProcess" to your project.
''response: -1 = service missing, 0 = stopped or stopping, 1 = running
imports System.ServiceProcess ''add this at top
Private Function GetServiceStatus(ByVal svcName As String) As Integer
Dim retVal As Integer
Dim sc As New ServiceController(svcName)
Try
If sc.Status.Equals(ServiceControllerStatus.Stopped) Or sc.Status.Equals(ServiceControllerStatus.StopPending) Then
retVal = 0
Else
retVal = 1
End If
Catch ex As Exception
retVal = -1
End Try
Return retVal
End Function
use it like this:
'' use taskManager to figure correct service name
dim svStatus as integer = GetServiceStatus("SMTP")
if svStatus <> 1 then
msgbox("Service not running or absent")
else
''write your send mail code here
end if
hope this will help you

Related

Vb.net application connect to multiple server via TCP/IP

I made a Winforms application to work with 4 different machines by connecting with them via TCP/IP. Somehow, the connection sometimes seems disconnected and reconnecting after a short while. May I know is it I used too much TCP client and caused them congested??
Below is the function/method to connect those machine...with 4 of them different function names to connect each of the machine, but the code is more or less the same:
Public Async Sub connect_Machine_Ethernet(ByVal mainForm As Form1)
If Machine_COMPort.IsOpen Then
Machine_COMPort.Close()
End If
If (IsNothing(Machine_client)) Then
'do nothing, since obj is not created
Else
Try
Machine_client.GetStream.Close()
Machine_client.Close()
Catch exp As Exception
End Try
End If
Try
Machine_client = New TcpClient
Machine_client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, True)
Dim result = Machine_client.BeginConnect(Machine_ModuleIP_txt.Text, CInt(Machine_ModulePort_txt.Text), Nothing, Nothing)
result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1))
Machine_client.GetStream.BeginRead(Machine_ethernet_buffer, 0, Machine_ethernet_buffer.Length, AddressOf Machine_TCP_read, Machine_ethernet_buffer)
DisplayMsg("Machine Ethernet connection established")
manual_connection_LED.StateIndex = 3
Machine_client_isConnected = True
Machine_TCP_Reconnect_btn.Invoke(Sub() Machine_TCP_Reconnect_btn.Visible = False)
Catch ex As Exception
DisplayMsg("Error : Unable to connect to the Machine Ethernet connection")
manual_connection_LED.StateIndex = 0
Machine_client_isConnected = False
If (IsNothing(Machine_client)) Then
'do nothing, since obj is not created
Else
Try
Machine_client.GetStream.Close()
Machine_client.Close()
Catch exp As Exception
End Try
End If
End Try
End Sub
'Read Machine TCP message
Sub Machine_TCP_read(ByVal ar As IAsyncResult)
Try
Dim buffer() As Byte = ar.AsyncState
Dim bytesRead As Integer = Machine_client.GetStream.EndRead(ar)
Dim Message As String = System.Text.Encoding.ASCII.GetString(Machine_ethernet_buffer, 0, bytesRead)
If Message = "" Then
'----check connection
If Machine_client.Connected Then
Machine_client.Close()
connect_Machine_Ethernet(Me)
End If
Else
DisplayMsg("Input Received from machine : " & Message)
Process_machine_Feedback(Message) 'perform any data logic from the message
Machine_client.GetStream.BeginRead(Machine_ethernet_buffer, 0, Machine_ethernet_buffer.Length, AddressOf Machine_TCP_read, Machine_ethernet_buffer)
End If
Catch ex As Exception
DisplaySystemMsg(ex.Message)
DisplayMsg("Marking machine Ethernet disconnected from the server")
manual_connection_LED.StateIndex = 0
Machine_client_isConnected = False
Exit Sub
End Try
End Sub
'Send message to TCP
Public Sub Machine_TCP_send(ByVal str As String)
Try
sWriter = New StreamWriter(Machine_client.GetStream)
sWriter.WriteLine(Chr(2) & str & Chr(3)) 'add prefix suffix
sWriter.Flush()
DisplayMsg("Message send to the machine via TCP: " & str)
Catch ex As Exception
DisplayMsg("Error : Message failed to send to themachine!")
End Try
End Sub

SSIS Script Task supress onerror

I have a script task which downloads a file using a HTTP connection object. This script task is part of a package which is called by another package. Sometimes the connection cannot be established. In these instances I want to retry the connection a number of times before finally raising an error if the connection attempts fail.
I tried to implement this. It appeared to work and the task does not fail. However an OnError event is still propagated every time an exception happens in the script task even though the script task doesn't fail. The fail occurs once control is passed from the child package back to the parent package.
Public Sub Main()
Dim tryTimes As Integer = 0
Dim maxTimes As Integer = 4
While (True)
Try
Dim nativeObject As Object = Dts.Connections("HTTP Connection Manager").AcquireConnection(Nothing)
'Create a new HTTP client connection
Dim connection As New HttpClientConnection(nativeObject)
Dim filename As String = Dts.Variables("Working_File").Value
connection.DownloadFile(filename, True)
Dts.TaskResult = ScriptResults.Success
Exit While
Catch ex As Exception
If (tryTimes < maxTimes) Then
tryTimes = tryTimes + 1
Thread.Sleep(30000)
Else
MsgBox(ex.Message)
Dts.TaskResult = ScriptResults.Failure
Throw
End If
End Try
End While
End Sub
I am hoping to get a solution where the OnError event is not called unless the connection attempts fails a certain number of times.
Try writing the same code an Fire a Warning on first 4 trial and on the 5th trial fire an error, i am not sure if it will works:
Public Sub Main()
Dim tryTimes As Integer = 0
Dim maxTimes As Integer = 4
While (True)
Try
Dim nativeObject As Object = Dts.Connections("HTTP Connection Manager").AcquireConnection(Nothing)
'Create a new HTTP client connection
Dim connection As New HttpClientConnection(nativeObject)
Dim filename As String = Dts.Variables("Working_File").Value
connection.DownloadFile(filename, True)
Dts.TaskResult = ScriptResults.Success
Exit While
Catch ex As Exception
If (tryTimes < maxTimes) Then
tryTimes = tryTimes + 1
Dts.Events.FireWarning(0, "Error ignored", _
"Retrying in 30 seconds", String.Empty, 0)
Thread.Sleep(30000)
Else
Dts.Events.FireError(-1, "", "Error message: " & ex2.ToString(), "", 0)
Dts.TaskResult = ScriptResults.Failure
End If
End Try
End While
End Sub
Reference
How to suppress OnError event for a specific error in a Script task (SSIS 2005)
You'll want to use a label, outside the try, and a GoTo within your catch
Public Sub Main()
Dim tryTimes As Integer = 0
Dim maxTimes As Integer = 4
RunCode: 'Label here
While (True)
Try
'your code here
Exit While
Catch ex As Exception
If (tryTimes < maxTimes) Then
tryTimes = tryTimes + 1
Thread.Sleep(30000)
GoTo RunCode 'after we catch the exception and eval tryTimes go back and retry
Else
'MsgBox(ex.Message)
Dts.Events.FireError(-1, "", "Error message: " & ex.ToString(), "", 0)
Dts.TaskResult = ScriptResults.Failure
'Throw
End If
End Try
End While
End Sub

send data grid view data in an e-mail using vb.net

i'm trying to send a datagridview (or just the data in the grid) to an e-mail but i only receive a blank e-mail when it's sent, anyone got any ideas how to fix it?
The code im using is this:
Try
SMTP.UseDefaultCredentials = False
SMTP.Credentials = New Net.NetworkCredential("[e-mail address im sending from]", "[password for that e-mail]")
SMTP.Port = 25
SMTP.EnableSsl = True
mail = New MailMessage
mail.From = New MailAddress("[e-mail im sending from]")
mail.To.Add(UserEmail.Text)
mail.Body = DataTab.ToString
mail.Subject = "Biology quiz Highscores"
SMTP.DeliveryMethod = SmtpDeliveryMethod.Network
SMTP.Send(mail)
MsgBox("E-mail sent to: " & UserEmail.Text & "")
Catch ex As Exception
MsgBox("Unable to send e-mail. Please try again later.")
End Try
im getting the data from a 2003 access database using mydataadpter sql statement, the data table variable is called datatab.
Object.ToString(), unless overridden, is identical to calling Object.GetType().ToString().
You want to show the data in the data table. You could do something like this:
Private Sub YourSubWhereYouSendEmail()
'...
Try
Using smtp = New SmtpClient() With {
.UseDefaultCredentials = False,
.Credentials = New Net.NetworkCredential("[e-mail address im sending from]", "[password for that e-mail]"),
.Port = 25,
.EnableSsl = True,
.DeliveryMethod = SmtpDeliveryMethod.Network
}
smtp.Send(New MailMessage("[e-mail im sending from]"), UserEmail.Text, "Biology quiz Highscores", DataTableToCSVString(DataTab)))
End Using
MsgBox("E-mail sent to: " & UserEmail.Text & "")
Catch ex As Exception
MsgBox("Unable to send e-mail. Please try again later.")
End Try
'...
End Sub
Private Function DataTableToCSVString(table As DataTable) As String
With New Text.StringBuilder
Dim once = False
'headers
For Each col As DataColumn In table.Columns
If once = False Then
once = True
Else
.Append(",")
End If
.Append(col.ColumnName)
Next
.AppendLine()
'rows
For Each s In table.Select.Select(Function(row) String.Join(",", row.ItemArray))
.AppendLine(s)
Next
Return .ToString
End With
End Function

System.Net.Mail VB.NET 3.5 System.Net.Mail.SmtpException

I have searched the net thoroughly for a solution to this and have yet to find one.
I'm trying to establish a simple mail client to send text documents as raw text through SMTP. To do this I am using the System.Net.Mail library under VB.Net version 3.5
Whenever I try to send a message, I receive a System.Net.Mail.SmtpException.
I have tried using different mail providers, under different settings and have yet to solve this problem. This problem has been tested on 3 separate computers, all with different specifications.
The code is as follows:
Private Sub SendEmailMessage()
Try
If My.Computer.Network.IsAvailable Then
If DataValid() Then
'Data is valid, send the eMail.
Dim MailReceiver As String = txtReceiver.Text
'Create the eMail Message.
'Dim message As New MailMessage(from:=txtMailAddress.Text, to:=MailReceiver, subject:="(MTG) <CARD> " & ID, body:="<p>" & ConstructedFileString() & "<p>")
Dim message As New MailMessage
Dim MessageFrom As New MailAddress(txtMailAddress.Text)
Dim MessageTo As New MailAddress(MailReceiver)
With message
.From = MessageFrom
.To.Add(MailReceiver)
.Subject = "(MTG) CARD " & ID
.IsBodyHtml = True
.Body = "<p>" & ConstructedFileString() & "<p>"
End With
'Establish eMail Client
Dim emailClient As New SmtpClient()
Dim emailCredentials As New Net.NetworkCredential
With emailCredentials
.UserName = txtMailAddress.Text
.Password = txtPassword.Text
.Domain = "gmail.com"
End With
With emailClient
.Host = txtHostServer.Text
.Port = txtPort.Text
.Credentials = emailCredentials
.EnableSsl = chkSSL.Checked
.Timeout = 5000
End With
'Dim MailDomain As String = ""
'Dim PositionAt As Byte = 0
'PositionAt = txtMailAddress.Text.IndexOf("#")
'For i = PositionAt + 1 To Len(txtMailAddress.Text)
' MailDomain = MailDomain & txtMailAddress.Text.Chars(i)
'Next
'Debug.Print(MailDomain)
If My.Computer.Network.Ping(hostNameOrAddress:=emailClient.Host) Then
'Send the message.
emailClient.Send(message)
Else
'Could not ping, do not send.
ErrorOut("Could not reach the eMail Server.")
End If
Else
'Data is not valid, do not send the eMail.
End If
Else
ErrorOut("No network could be found. Check your network configurations.")
End If
Catch ex As Security.SecurityException
'Security exception
ErrorOut("A Security Exception was raised.")
Catch ex As Net.NetworkInformation.NetworkInformationException
'Network info exception
ErrorOut("Exception raised when retrieving network information.")
Catch ex As Net.NetworkInformation.PingException
'Ping exception
ErrorOut("Exception raised when pinging the network.")
Catch ex As Net.Mail.SmtpFailedRecipientException
'Recipient exception
ErrorOut("Mail Recipient Exception raised.")
Catch ex As Net.Mail.SmtpException
'Mail Server Exception
ErrorOut("Mail Server Exception raised")
Catch ex As Exception
'Generic Exception raised.
ErrorOut("General Exception raised", True)
End Try
End Sub
Any help on this matter is greatly appreciated, thanks.
Stack trace:
System.Net.Mail.SmtpException: The operation has timed out.
at System.Net.Mail.SmtpClient.Send(MailMessage message)
at NetProj.EmailDialog.SendEmailMessage() in ...
I believe this is the famous SSL issue with System.Net.Mail
http://blogs.msdn.com/b/webdav_101/archive/2008/06/02/system-net-mail-with-ssl-to-authenticate-against-port-465.aspx
It was there in framework 3.5 not sure about 4.0 if they fixed it or not.

What is the usual way to check if internet connection exists and if SMTP mail is sent?

I'm sending emails through VB.NET like in showed code:
Dim retval As Integer
Dim attachment As System.Net.Mail.Attachment = Nothing
If fileName <> "" Then
attachment = New System.Net.Mail.Attachment(fileName)
End If
Dim client As New SmtpClient()
With client
.EnableSsl = True
.Host = smtpServerAddress
.Port = 587
.DeliveryMethod = SmtpDeliveryMethod.Network
.UseDefaultCredentials = False
.Credentials = New NetworkCredential(FromEmailId, password)
AddHandler .SendCompleted, AddressOf SendCompletedCallback
End With
Dim mail = New MailMessage(FromEmailId, toEmailId)
With mail
.Priority = MailPriority.High
.Subject = subject
.SubjectEncoding = System.Text.Encoding.UTF8
.IsBodyHtml = False
If fileName <> "" Then
.Attachments.Add(attachment)
End If
.Body = msgBody
.BodyEncoding = System.Text.Encoding.UTF8
End With
Try
client.SendAsync(mail, "")
retval = 1
Catch ex As Exception
retval = 0
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
Return retval
This work's well.
Problem is only that my Try/Catch block dont react as expected if I'm not connected to internet. The only way I can know that mail didn't go out is that I don't receive message from callback what can take a long time. Also, I get returned 1 from function like email is sended properly.
Which is usual way to check if internet connection exists and if mail is start to be sended?
If you want to catch all exception thrown from SmtpClient you could send mail synchronously. If you prefer asynchronous way, use SendMailAsync which returns Task instance on which you can call ContinueWith to set error handler:
client.SendMailAsync(mail).ContinueWith(t=>HandleError(t.Exception), TaskContinuationOptions.OnlyOnFaulted)