Rank: Administration
Groups: Administrators
Joined: 11/11/2010(UTC) Posts: 1,153
Thanks: 9 times Was thanked: 55 time(s) in 55 post(s)
|
Visual Basic.NET ExampleIf you want to leave a copy of email on the server, you should not call Delete method. However, there is a problem, how can you know if the email has already been downloaded (read)? If there is a way to identify the downloaded email, you can avoid downloading the duplicated email from your POP3/IMAP4 server. Every email has a unique identifier (UIDL) on POP3 server. POP3 UIDL is only unique in the email life time. That means if the email was deleted from the server, other email can use the old unique identifier. Another problem is: UIDL in POP3 server can be any number or characters, so we cannot use UIDL as the file name, because UIDL may contain invalid characters for file name. To solve this problem, we have to store the UIDL to a txt file and synchronize it with server every time. The following example codes demonstrate how to mark the email as downloaded/read on POP3 server. Code:
' The following example codes demonstrate marking email as read/downloaded on POP3 server
' To get full sample projects, please download and install EAGetMail on your machine.
' To run it correctly, please change email server, user, password, folder, file name value to yours
Imports System.Collections
Imports System.Text
Imports System.IO
' Imports EAGetMail namespace
Imports EAGetMail
Module Module1
Public Class MyMailClient
Private m_arUidl As ArrayList = New ArrayList
Private m_uidlfile As String = "uidl.txt"
Private m_curpath As String = ""
#Region "UIDL Functions"
' Uidl is the identifier of every email on POP3/IMAP4 server, to avoid
' retrieve the same email from server more than once, we record the
' email uidl retrieved every time if you delete the email from server
' every time and not to leave a copy of email on the server, then please
' remove all the function about uidl.
Private Function _FindUIDL(ByVal infos() As MailInfo, ByVal uidl As String) As Boolean
Dim count As Integer = infos.Length
For i As Integer = 0 To count - 1
If String.Compare(infos(i).UIDL, uidl, False) = 0 Then
_FindUIDL = True
Exit Function
End If
Next
_FindUIDL = False
End Function
' Remove the local uidl which is not existed on the server.
Private Sub _SyncUIDL(ByVal oServer As MailServer, ByVal infos() As MailInfo)
Dim s As String = String.Format("{0}#{1} ", oServer.Server, oServer.User)
Dim bcontinue As Boolean = False
Dim n As Integer = 0
Do
bcontinue = False
Dim count As Integer = m_arUidl.Count
For i As Integer = n To count - 1
Dim x As String = m_arUidl(i)
If String.Compare(s, 0, x, 0, s.Length, True) = 0 Then
Dim pos As Integer = x.LastIndexOf(" ")
If pos <> -1 Then
Dim uidl As String = x.Substring(pos + 1)
If (Not _FindUIDL(infos, uidl)) Then
' this uidl doesn't exist on server,
' we should remove it from local uidl list.
bcontinue = True
n = i
m_arUidl.RemoveAt(i)
Exit For
End If
End If
End If
Next
Loop While (bcontinue)
End Sub
Private Function _FindExistedUIDL(ByVal oServer As MailServer, _
ByVal uidl As String) As Boolean
Dim s As String = String.Format("{0}#{1} {2}", _
oServer.Server.ToLower(), oServer.User.ToLower(), uidl)
Dim count As Integer = m_arUidl.Count
For i As Integer = 0 To count - 1
Dim x As String = m_arUidl(i)
If String.Compare(s, x, False) = 0 Then
_FindExistedUIDL = True
Exit Function
End If
Next
_FindExistedUIDL = False
End Function
Private Sub _AddUIDL(ByVal oServer As MailServer, ByVal uidl As String)
Dim s As String = String.Format("{0}#{1} {2}", _
oServer.Server.ToLower(), oServer.User.ToLower(), uidl)
m_arUidl.Add(s)
End Sub
Private Sub _UpdateUIDL()
Dim s As New StringBuilder
Dim count As Integer = m_arUidl.Count
For i As Integer = 0 To count - 1
s.Append(m_arUidl(i))
s.Append(vbCrLf)
Next
Dim file As String = String.Format("{0}\{1}", m_curpath, m_uidlfile)
Dim fs As FileStream = Nothing
Try
fs = New FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None)
Dim data() As Byte = System.Text.Encoding.Default.GetBytes(s.ToString())
fs.Write(data, 0, data.Length)
fs.Close()
Catch ep As Exception
If Not (fs Is Nothing) Then
fs.Close()
End If
Throw ep
End Try
End Sub
Private Sub _LoadUIDL()
m_arUidl.Clear()
Dim filename As String = String.Format("{0}\{1}", m_curpath, m_uidlfile)
Dim read As StreamReader = Nothing
Try
read = File.OpenText(filename)
Do While (True)
Dim line As String = read.ReadLine().Trim(vbCrLf & " " & vbTab.ToCharArray())
m_arUidl.Add(line)
Loop
Catch ep As Exception
End Try
If Not (read Is Nothing) Then
read.Close()
End If
End Sub
#End Region
Public Sub ReceiveEmail(ByVal oServer As MailServer, ByVal bLeaveCopy As Boolean)
Dim oClient As New MailClient("TryIt")
m_curpath = Directory.GetCurrentDirectory()
Try
' Uidl is the identifier of every email on POP3/IMAP4 server, to
' avoid retrieve the same email from server more than once,
' we record the email uidl retrieved every time if you delete the
' email from server every time and not to leave a copy of email on
' the server, then please remove all the function about uidl.
_LoadUIDL()
Dim mailFolder As String = [String].Format("{0}\inbox", m_curpath)
If Not Directory.Exists(mailFolder) Then
Directory.CreateDirectory(mailFolder)
End If
Console.WriteLine("Connecting server ... ")
oClient.Connect(oServer)
Dim infos As MailInfo() = oClient.GetMailInfos()
Console.WriteLine("Total {0} email(s)", infos.Length)
_SyncUIDL(oServer, infos)
Dim count As Integer = infos.Length
For i As Integer = 0 To count - 1
Dim info As MailInfo = infos(i)
If _FindExistedUIDL(oServer, info.UIDL) Then
' this email has existed on local disk.
Continue For
End If
Console.WriteLine("Retrieving {0}/{1}...", info.Index, count)
Dim oMail As Mail = oClient.GetMail(info)
Dim d As System.DateTime = System.DateTime.Now
Dim cur As New System.Globalization.CultureInfo("en-US")
Dim sdate As String = d.ToString("yyyyMMddHHmmss", cur)
Dim fileName As String = [String].Format("{0}\{1}{2}{3}.eml", _
mailFolder, sdate, d.Millisecond.ToString("d3"), i)
oMail.SaveAs(fileName, True)
If bLeaveCopy Then
' Add the email uidl to uidl file to avoid we retrieve it next time.
_AddUIDL(oServer, info.UIDL)
End If
Next
If Not bLeaveCopy Then
Console.WriteLine("Deleting ...")
For i As Integer = 0 To count - 1
oClient.Delete(infos(i))
Next
End If
Console.WriteLine("Completed")
oClient.Quit()
Catch ep As Exception
Console.WriteLine(ep.Message)
End Try
' Update the uidl list to a text file and then we can load it next time.
_UpdateUIDL()
End Sub
End Class
Sub Main()
' Create a folder named "inbox" under current directory
' to save the email retrieved.
Dim curpath As String = Directory.GetCurrentDirectory()
Dim mailbox As String = [String].Format("{0}\inbox", curpath)
' If the folder is not existed, create it.
If Not Directory.Exists(mailbox) Then
Directory.CreateDirectory(mailbox)
End If
Dim oServer As New MailServer("pop3.emailarchitect.net", _
"test@emailarchitect.net", "testpassword", ServerProtocol.Pop3)
Dim oClient As New MailClient("TryIt")
' If your POP3 server requires SSL connection,
' Please add the following codes:
' oServer.SSLConnection = True
' oServer.Port = 995
Dim MyClient As New MyMailClient
MyClient.ReceiveEmail(oServer, True)
End Sub
End Module
Click here to read original topic - full version ...If you have any comments or questions about above example codes, please add your comments here.
|