POP3 and SMTP in Visual Basic .NET 2008

Internet, Visual Basic .NET Add comments

LeeJoo Mail(Probably) all of you get email, and just like this guy next to this text, we all are very happy with it :-p

I recently switched from VB.NET 2003 to 2008 and I wanted to do  something with e-mail. So here is a DLL to read/download (POP3) email and to send (SMTP) email.

For the ones who just want the code: (download below)

POP3

Imports System
Imports System.Net.Sockets
Imports System.Text
Imports System.IO

Public Class POP3

    Private Shared Server As TcpClient
    Private Shared NetStrm As NetworkStream
    Private Shared RdStrm As StreamReader

    Public Shared Function Connect(ByVal POP3Server As String, ByVal User As String, ByVal Password As String) As Boolean
        If POP3Server.Trim = “” Then
            Return False
        End If
        Try
            Server = New TcpClient(POP3Server.Trim, 110)
            NetStrm = Server.GetStream
            RdStrm = New StreamReader(Server.GetStream)
        Catch exc As Exception
            Return False
        End Try
        If RunQuery(”USER ” & User.Trim).Substring(0, 3) <> “+OK” Then
            Return False
        End If
        If RunQuery(”PASS ” & Password).Substring(0, 3) <> “+OK” Then
            Return False
        End If
        Return True
    End Function

    Public Shared Sub Disconnect()
        Dim data As String = “Quit ” & vbCrLf
        Dim szData() As Byte = System.Text.Encoding.ASCII.GetBytes(data.ToCharArray())
        NetStrm.Write(szData, 0, szData.Length)
        Dim tmpString As String = RdStrm.ReadLine()
    End Sub

    Public Shared Function DeleteMessage(ByVal msgIndex As Integer) As Boolean
        If RunQuery(”DELE ” & msgIndex.ToString).Substring(0, 4) = “-ERR” Then
            Return False
        Else
            Return True
        End If
    End Function

    Public Shared Function NumberOfMessages() As Integer
        If RunQuery(”STAT”).Substring(0, 4) = “-ERR” Then
            Return -1
        End If
        Dim Stat As String = RunQuery(”STAT”)
        If Stat.Substring(0, 4) = “-ERR” Then
            Return -1
        End If
        Dim Number() As String
        Number = Stat.Split(” “)

        Return CInt(Number(1))
    End Function

    Public Structure Message
        Dim _From As String
        Dim _To As String
        Dim _Date As String
        Dim _Subject As String
        Dim _CC As String
        Dim _BCC As String
        Dim _Body As String
        Dim _Received As String
    End Structure

    Public Function ReadMessage(ByVal MsgIndex As Integer) As Message
        Dim Response As String
        Dim MsgText As String = “”
        Dim MsgReturn As New Message
        Dim BrkPos As Integer
        Dim Header As String
        Dim Headers() As String
        Dim Body As String
        Dim HeaderName As String
        Dim HeaderValue As String

        Try
            Response = RunQuery(”RETR ” & MsgIndex.ToString)
            If Response.Substring(0, 4) <> “-ERR” Then
                While (Response <> “.”)
                    MsgText = MsgText & Response & vbCrLf
                    Response = RdStrm.ReadLine
                End While
            End If
        Catch exc As InvalidOperationException
            Throw New Exception(”Message Retrival Failed: ” & vbCrLf & Err.ToString())
            Exit Function
        End Try

        BrkPos = InStr(1, MsgText, vbCrLf & vbCrLf)
        If BrkPos Then
            Header = MsgText.Substring(0, BrkPos - 1)
            Body = MsgText.Substring(BrkPos + 1, _
            MsgText.Length - Header.Length - 3)
            MsgReturn._Body = Body
        Else
            Throw New Exception(”Invalid Message Format”)
            Exit Function
        End If

        Headers = Split(Header, vbCrLf)
        Dim _header As String
        For Each _header In Headers
            BrkPos = _header.IndexOf(”:”)
            If BrkPos >= 0 Then
                HeaderName = _header.Substring(0, BrkPos)
            Else
                HeaderName = “”
            End If
            HeaderValue = _header.Substring(BrkPos + 1)
            Select Case HeaderName.ToLower
                Case “received”
                    MsgReturn._Received = HeaderValue
                Case “from”
                    MsgReturn._From = HeaderValue
                Case “to”
                    MsgReturn._To = HeaderValue
                Case “cc”
                    MsgReturn._CC = HeaderValue
                Case “bcc”
                    MsgReturn._BCC = HeaderValue
                Case “subject”
                    MsgReturn._Subject = HeaderValue
                Case “date”
                    MsgReturn._Date = HeaderValue
            End Select
        Next

        Return MsgReturn
    End Function

    Private Shared Function RunQuery(ByVal Query As String) As String
        Query = Query & vbCrLf
        Dim Data() As Byte = System.Text.Encoding.ASCII.GetBytes(Query.ToCharArray())
        NetStrm.Write(Data, 0, Data.Length)
        Dim Response As String = RdStrm.ReadLine

        Return Response
    End Function

End Class


STMP

Imports System.Net.MailPublic

Class SMTPPublic

    Shared Function SendMail(ByVal MServer As String, _
      ByVal MFrom As String, _
      ByVal MTo As String, _
      ByVal MSubject As String, _
      ByVal MBody As String, _
      Optional ByVal MBodyHTML As Boolean = False, _
      Optional ByVal MCC As String = Nothing, _
      Optional ByVal MBCC As String = Nothing, _
      Optional ByVal MAttachment As String = Nothing, _
      Optional ByVal MServerUser As String = Nothing, _
      Optional ByVal MServerPass As String = Nothing, _
      Optional ByVal MServerPort As Integer = 25, _
      Optional ByVal MServerSLL As Boolean = False) As Boolean
        Try
            Dim Mail As New System.Net.Mail.MailMessage
            With Mail
                .From = New MailAddress(MFrom)
                .To.Add(MTo)
                .Subject = MSubject
                .IsBodyHtml = MBodyHTML
                .Body = MBody
                If MBCC = Not Nothing Then .Bcc.Add(MBCC)
                If MCC = Not Nothing Then .CC.Add(MCC)
                If MAttachment = Not Nothing Then
                    Dim attachments() As String = Strings.Split(MAttachment, “;”)
                    Dim i As Integer
                    For i = 0 To UBound(attachments)
                        .Attachments.Add(New Attachment(attachments(i)))
                    Next
                End If
            End With
            Dim SMTP As New SmtpClient(MServer)
            If MServerUser.Length + MServerPass.Length > 0 Then
                SMTP.Credentials = New Net.NetworkCredential(MServerUser, MServerPass)
            End If
            SMTP.Port = MServerPort
            SMTP.Host = MServer
            SMTP.EnableSsl = MServerSLL
            SMTP.Send(Mail)
            SMTP = Nothing
            Mail.Dispose()
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function
End Class


Download MailProtocol DLL 

For the one of us who just want the DLL file, also download it, the DLL file is in the ‘bin’-folder.I created this DLL in VB.NET 2008 but it might be easily convertible to older copies.

Pakku

Share/Save/Bookmark

14 Responses to “POP3 and SMTP in Visual Basic .NET 2008”

  1. Michael B Says:

    Hello,

    Your MailProtocol DLL seems really wonderful, but for some bizarre reason I can’t seem to get it to work. It connects successfully to my mail server, and reports that there are no messages. Am I doing something wrong?

    POP3.Connect(”pop.MYSERVER.com”, “MYEMAIL”, “MYPASSWORD”)
    MsgBox(POP3.NumberOfMessages())
    POP3.Disconnect()

    I am using the server 1and1, if that helps.

  2. Michael B Says:

    Argh… stupid smileys.

  3. Pakku Says:

    @Michael B
    POP3.NumberOfMessages() returns an integer. To show it in a MsgBos, you’ll need to convert it to a string by using POP3.NumberOfMessages().ToString
    It also can return zero because there simply isn’t an e-mail message in your inbox :P
    Pakku

  4. Michael B Says:

    Hello again,

    I’m pretty sure you can msgbox integers too, but regardless there are messages in my inbox when I use this function and it still gives me a zero (even using the .ToString method).

    My syntax is correct, isn’t it? And I’m using all of the necessary functions? I’ve tried reading specific E-Mails by index number and that doesn’t work either… is there something else going on?

  5. Michael B Says:

    Wait a minute…

    Looking at your Connect code, at the very end it says Return True… even if it went through all that other stuff and was meant to Return False, won’t it just Return True regardless? Does this mean it may not be connecting to my server successfully and I just don’t know it?

  6. Michael B Says:

    And it’s me one more time.

    It turns out I was probably wrong about the Connect function returning True all of the time, but either way I tried this with my Yahoo account now and it’s reporting -1, whether I use @yahoo.com or not. I know I’m using the right password too, and I checked my Yahoo mail manually and saw that there were a lot of messages in the Inbox.

    Am I the only one having issues here? lol.

  7. Pakku Says:

    @Micael B
    You again :P Are you sure your server(s) support POP3? Doesn’t block your firewall your connection?
    I tested it and for me it works fine. About the Return True thing, if you return something, the function exits itself, so after returning something, the next code will not be run.

    Pakku

    EDIT: I uploaded the code again, it might be that you have copied it in a strange way and that the code in your program is slightly different than mine.

  8. Michael B Says:

    I know 1and1 allows POP3 because I’ve used it in other applications (Microsoft Outlook and Outlook Express, for instance). I’m pretty sure Yahoo allows it too, or else why would they provide information for it?

    Thanks for clearing up the Return thing for me, that’s good to know.

    I’ll try the re-uploaded code and see if it works for me. Thanks!

  9. Michael B Says:

    Well, I tried the new, italicized code that you posted here on your page… I made a couple of new classes in my project and copied and pasted this to them (naming said classes POP3 and SMTP), and called the methods from those classes as before. Once again it said there were no messages on my server, and this time I even marked them all as unread and tried it… the same thing happened.

    Could it still be a firewall problem? This isn’t the computer I use at home (although this is the computer I use Outlook with), so maybe I’ll try it at home and see if anything changes.

    Could it be something else yet? Does anyone else use this code? This is the closest I’ve come to E-Mail functionality yet, heh.

  10. Michael B Says:

    Well, I’m not sure WHAT I did differently, but I fiddled around and got it to finally work! I can see that I have one E-Mail, and I figured out how to send mail as well. PHEW.

    (My theory is that your function gets only the number of unread messages, and that it takes a while for a message to show up as “unread” if you mark it as such. I had read messages, and the ones I marked unread must not have refreshed with the server yet.)

    Thanks for your help!

  11. Michael B Says:

    Umm, that was weird… it did work, and now it won’t again. Oh, son of a.

    I got a 1 for number of messages, and I got a True for SendMail. It’s saying 0 again even though I haven’t touched my inbox, and the mail I supposedly sent never showed up.

    Blargh, lol.

  12. Michael B Says:

    Wait again… the mail I sent did show up. So it’s just the reading of the mail that I’m having issues with.

    Could I possibly spam this page more, by the way? Sorry about all this.

  13. Michael B Says:

    I finally figured it all out.

    For 1and1, Outlook has been deleting the mail it downloads off of the server, but keeping it on the machine’s drive. I was under the illusion this whole time that the mail was still on the server, and it wasn’t.

    The one time I saw 1 message, that E-Mail hadn’t been downloaded by Outlook yet.

    And Yahoo doesn’t support free POP3, you have to sign up for it (and pay, I assume). So it connects but doesn’t allow me to do anything, which is why I keep getting -1 messages.

    El oh el. I can’t believe it, it’s worked all along. Thanks for everything!

  14. Pakku Says:

    @Michael B
    Good to hear you figured it out. Outlook, Outlook Express, Windows Mail and likely most other mailcleint indeed downloads the mesages from the server and deletes them on the server. So this means that the functions only check the mail left on the server. If you use these functions after you checked your e-mail with the above programs, the functions should return 0 messages left (unless you just received a new mail) just because there are now messages left on the server because they are all on your own system.

    Pakku

Leave a Reply

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in