Delete email messages with IMAP

This article describes how to delete email messages using Mail.dll .NET IMAP library and IMAP protocol.

Internally deleted messages are flagged with \DELETED flag and are actually deleted after the client issues EXPUNGE command. Mail.dll issues this command automatically.

Following code will find unique ids of all unseen messages in the Inbox folder and delete them one by one.

// C#

using Limilabs.Client.IMAP;
using Limilabs.Mail;
using System;
using System.Collections.Generic;


class Program
{
    static void Main(string[] args)
    {
        using (Imap imap = new Imap())
        {
            imap.Connect("imap.example.com");    // use ConnectSSL for SSL.
            imap.Login("user", "password");

            imap.SelectInbox();
            List<long> uids = imap.Search(Flag.Unseen);
            foreach (long uid in uids)
            {
                imap.DeleteMessageByUID(uid);
            }
            imap.Close();
        }
    }
};
' VB.NET

Imports Limilabs.Mail
Imports Limilabs.Client.IMAP
Imports System
Imports System.Collections.Generic

Public Module Module1
    Public Sub Main(ByVal args As String())

        Using imap As New Imap()
            imap.Connect("imap.example.com")    ' use ConnectSSL for SSL.
            imap.Login("user", "password")

            imap.SelectInbox()
            Dim uids As List(Of Long) = imap.Search(Flag.Unseen)
            For Each uid As Long In uids
                imap.DeleteMessageByUID(uid)
            Next
            imap.Close()
        End Using

    End Sub
End Module

You can also use bulk delete methods, which are much faster when operating on large number of unique ids. This is because EXPUNGE command is issued only once.

// C#

using (Imap imap = new Imap())
{
    imap.Connect("imap.example.com");    // use ConnectSSL for SSL.
    imap.Login("user", "password");

    imap.SelectInbox();
    List<long> uids = imap.Search(Flag.Unseen);

    imap.DeleteMessageByUID(uids);

  imap.Close();
}
' VB.NET

Public Module Module1
    Public Sub Main(ByVal args As String())

        Using imap As New Imap()
            imap.Connect("imap.example.com")    ' use ConnectSSL for SSL.
            imap.Login("user", "password")

            imap.SelectInbox()
            Dim uids As List(Of Long) = imap.Search(Flag.Unseen)

            imap.DeleteMessageByUID(uids)

            imap.Close()
        End Using

    End Sub
End Module

Gmail server behaves a bit differently than most IMAP server please read the delete emails from Gmail for details.

Get common email fields (Subject, Text) with IMAP

In this article we’ll show how to download emails using Mail.dll IMAP client and access some common email properties like: Subject, Date, Html, Text and Attachments.

Remember about adding a reference to Mail.dll and importing namespaces.

First you need to download email from IMAP server using Imap class. Then parse it using MailBuilder class. After that you’ll receive IMail interface.

This interface can be used to access all standard and non-standard headers.
Subject, From, To, Date, email data like: Text and Html versions of the email, and others can be accessed as simple properties. This sample also shows how to access Attachments collection.

// C#

using System;
using System.Collections.Generic;
using Limilabs.Client.IMAP;
using Limilabs.Mail;
using Limilabs.Mail.MIME;
using Limilabs.Mail.Headers;

class Program
{
    static void Main(string[] args)
    {
        using(Imap imap = new Imap())
        {
            imap.Connect("imap.example.com");    // use ConnectSSL for SSL
            imap.UseBestLogin("user", "password");

            imap.SelectInbox();
            List<long> uids = imap.Search(Flag.Unseen);

            foreach (long uid in uids)
            {
                var eml = imap.GetMessageByUID(uid);
                IMail email = new MailBuilder()
                    .CreateFromEml(eml);

                // Subject
                Console.WriteLine(email.Subject);

                // From
                foreach (MailBox m in email.From)
                {
                    Console.WriteLine(m.Address);
                    Console.WriteLine(m.Name);
                }

                // Date
                Console.WriteLine(email.Date);

                // Text body of the message
                Console.WriteLine(email.Text);

                // Html body of the message
                Console.WriteLine(email.Html);

                // Custom header
                Console.WriteLine(email.Document.Root.Headers["x-spam"]);

                // Save all attachments to disk
                foreach (MimeData mime in email.Attachments)
                {
                    mime.Save(@"c:\" + mime.SafeFileName);
                }
            }
            imap.Close();
        }
    }
};
' VB.NET

Imports Limilabs.Client.IMAP
Imports Limilabs.Mail
Imports Limilabs.Mail.MIME
Imports Limilabs.Mail.Headers
Imports System
Imports System.Collections.Generic

Public Module Module1
    Public Sub Main(ByVal args As String())

        Using imap As New Imap()
            imap.Connect("pop3.example.com")    ' use ConnectSSL for SSL
            imap.UseBestLogin("user", "password")

            imap.SelectInbox()
            Dim uids As List(Of Long) = imap.Search(Flag.Unseen)

            For Each uid As Long In uids
                Dim eml = imap.GetMessageByUID(uid)
                Dim email As IMail = New MailBuilder() _
                    .CreateFromEml(eml)

                ' Subject
                Console.WriteLine(email.Subject)

                ' From
                For Each m As MailBox In email.From
                    Console.WriteLine(m.Address)
                    Console.WriteLine(m.Name)
                Next

                ' Date
                Console.WriteLine(email.[Date])

                ' Text body of the message
                Console.WriteLine(email.Text)

                ' Html body of the message
                Console.WriteLine(email.Html)

                ' Custom header
                Console.WriteLine(email.Document.Root.Headers("x-spam-value"))

                ' Save all attachments to disk
                For Each mime As MimeData In email.Attachments
                    mime.Save("c:\" + mime.SafeFileName)
                Next
            Next
            imap.Close()
        End Using

    End Sub
End Module

To, Cc and Bcc headers are a bit tricky as they can contain address groups. You can learn more about how to work with them in how to access To, Cc, Bcc fields article.

Receive unseen emails using IMAP

This article describes how to receive unseen email messages using Mail.dll .net email library and IMAP protocol.

As a prerequisite you need to add reference to Mail.dll to your project. Please check MSDN how to add reference article for details.

When your reference is added you need to import correct namespaces:

// C#

using Limilabs.Mail;
using Limilabs.Client.IMAP;
' VB

Imports Limilabs.Mail
Imports Limilabs.Client.IMAP

First thing you need to do is to connect to your IMAP server.

Use Connect(string host) method to connect to the server. Typically IMAP server is working on port 143. You can use Connect(string host, int port) overload when you need to specify different port, or ConnectSSL methods to use IMAP over TLS/SSL.

// C#

using (Imap imap = new Imap ())
{
    imap.ConnectSSL("imap.example.com");  // or Connect for no SSL
    imap.UseBestLogin("user", "password");

' VB

Using imap As New Imap ()
    imap.ConnectSSL("imap.example.com")  ' or Connect for no SSL
    imap.UseBestLogin("user", "password")

Mail.dll supports OAuth 2.0 for authentication, you can find OAuth2 samples for Office365 and Gmail on the Mail.dll samples page.

For Gmail you may want to use Gmail’s App Passwords.

Next step is to select folder, download unique ids (uids) of unseen messages, and iterate through them. In this example we select Inbox, but you can use Select method to select different folder.

// C#

imap.SelectInbox();

List<long> uids = imap.Search(Flag.Unseen);
foreach (long uid in uids)
' VB

imap.SelectInbox()

Dim uids As List(Of Long) = imap.Search(Flag.Unseen)
For Each uid As Long In uids

Finally we’ll use GetMessageByUID method to download the message from the server and MailBuilder class to parse email and extract attachments:

// C#

var eml = imap.GetMessageByUID(uid)
IMail email = new MailBuilder().CreateFromEml(eml);

string subject = email.Subject;
string plainText = email.Text;
' VB

Dim eml = imap.GetMessageByUID(uid)
Dim email As IMail = builder.CreateFromEml(eml)

Console.WriteLine(email.Subject)
Console.WriteLine(email.Text)

At that point you can also access and proceses email attachments.

Here are the full samples showing how to receive e-mail messages in C# and VB.NET:

// C#

using Limilabs.Mail;
using Limilabs.Client.IMAP;

class Program
{
    static void Main(string[] args)
    {
        using(Imap imap = new Imap())
        {
            imap.ConnectSSL("imap.example.com"); // or Connect
            imap.UseBestLogin("user", "password");

            imap.SelectInbox();
            List<long> uids = imap.Search(Flag.Unseen);

            foreach (long uid in uids)
            {
                var eml = imap.GetMessageByUID(uid);
                IMail email = new MailBuilder()
                    .CreateFromEml(eml);

                string subject = email.Subject;
                string plainText = email.Text;
            }
            imap.Close();
        }
    }
};
' VB.NET

Imports Limilabs.Mail
Imports Limilabs.Client.IMAP

Public Module Module1
    Public Sub Main(ByVal args As String())
        Using imap As New Imap()
            imap.ConnectSSL("imap.example.com") ' or Connect
            imap.UseBestLogin("user", "password")

            imap.SelectInbox()
            Dim uids As List(Of Long) = imap.Search(Flag.Unseen)

            For Each uid As Long In uids
                Dim eml = imap.GetMessageByUID(uid)
                Dim email As IMail = New MailBuilder() _
                    .CreateFromEml(eml)

                Console.WriteLine(email.Subject)
                Console.WriteLine(email.Text)
            Next
            imap.Close()
        End Using
    End Sub
End Module

Just give Mail.dll a try and download it at: Mail.dll .NET email component


Get Mail.dll

Update NuSpec version from MsBuild

Here’s the sample script that updates NuGet version node in NuSpec file:

<target Name="UpdateNuspec">
    <getAssemblyIdentity AssemblyFiles="$(ReleaseFolder)/Redistributables/YourAssembly.dll">
      <output TaskParameter="Assemblies" ItemName="YourAssemblyInfo"/>
    </getAssemblyIdentity>
    <xmlUpdate
        Prefix="nu"
        Namespace="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"
        XmlFileName="YourAssembly.nuspec"
        XPath="package/nu:metadata/nu:version"
        Value="%(YourAssemblyInfo.Version)"/>
</target>

Gmail’s POP3 behavior

First remember to enable POP3 in Gmail.

Gmail’s POP3 configuration maybe sometimes confusing.

In the Gmail’s web interface in “Settings” on “Forwarding and POP/IMAP” tab in “POP Download” you’ll find drop down list called “When messages are accessed with POP“.

Here’s the value list and the Gmail’s behavior:

  • “keep Gmail’s copy in the Inbox”:
    Message stays in the Inbox,
    web interface says it’s unread,
    message is not received for the second time when using POP3 client.
  • “mark Gmail’s copy as read”:
    Message stays in the Inbox,
    web interface says it’s read,
    message is not received for the second time when using POP3 client.
  • “archive Gmail’s copy”:
    Message is removed from Inbox by issuing GetMessageByNumber or GetMessageByUID command,
    in web interface you can find it in ‘All Mail’,
    message is not received for the second time when using POP3 client.
  • “delete Gmail’s copy”:
    Message is deleted by issuing GetMessageByNumber or GetMessageByUID command,
    in web interface you can find it in ‘Trash’ for 30 days,
    message is not received for the second time when using POP3 client.

Recent mode

If you’re accessing Gmail on multiple clients through POP, Gmail’s ‘recent mode’ makes sure that all messages are made available to each client, rather than only to the first client to access new mail.

Recent mode fetches the last 30 days of mail, regardless of whether it’s been sent to another POP3 client already.

To enable recent mode you need to replace “username@gmail.com” specified in User property with “recent:username@gmail.com”.
Also you should not be using DeleteMessage or DeleteMessageByUID methods.

Consider using IMAP

If you want to have a greater control over your emails you should use IMAP protocol.

With IMAP you can:

Check POP3 vs IMAP for details.

Mail.dll contains ready to use IMAP client. Take a look on how to download email from Gmail using IMAP sample.