Process emails embedded as attachments

This article describes how to process emails embedded within emails as attachments. Mail.dll supports opening and extraction of embedded emails and attachments within.

Extracting all attachments

There is an easy way out – using ExtractAttachmentsFromInnerMessages method. It extracts all attachments from the email and from all attached messages. It returns easy to use collection of MimeData objects that represent each attachment.

// C#

using (Imap client = new Imap())
{
    client.ConnectSSL("imap.example.com");
    client.UseBestLogin("user", "password");
    client.SelectInbox();
    foreach (long uid in client.GetAll())
    {
        IMail mail = new MailBuilder().CreateFromEml(
            client.GetMessageByUID(uid));

        ReadOnlyCollection<MimeData> attachments = 
            mail.ExtractAttachmentsFromInnerMessages();
      
        foreach (MimeData mime in attachments)
        {
            mime.Save(@"c:\" + mime.SafeFileName);
        }
    }
    client.Close();
}
' VB.NET version

Using client As New Imap()
    client.ConnectSSL("imap.example.com")
    client.UseBestLogin("user", "password")
    client.SelectInbox()
    For Each uid As Long In client.GetAll()
        Dim mail As IMail = New MailBuilder() _
            .CreateFromEml(client.GetMessageByUID(uid))

        Dim attachments As ReadOnlyCollection(Of MimeData) _
            = mail.ExtractAttachmentsFromInnerMessages()

        For Each mime As MimeData In attachments
            mime.Save("c:\" + mime.SafeFileName)
        Next
           
    Next
    client.Close()
End Using

Manual approach

This gives you more control of which attachments to process, and which for some reason you wisch to ignore. We’ll create a simple method that processes all attached emails and extracts all attachments to specified folder.

First we’ll use Mail.dll IMAP component to download emails:

// C#

using (Imap client = new Imap())
{
    client.ConnectSSL("imap.example.com");
    client.UseBestLogin("user", "password");
    client.SelectInbox();
    foreach (long uid in client.GetAll())
    {
        IMail mail = new MailBuilder().CreateFromEml(
            client.GetMessageByUID(uid));

        SaveAttachmentsTo(mail, @"c:\tmp");
    }
    client.Close();
}
' VB.NET version

Using client As New Imap()
    client.ConnectSSL("imap.example.com")
    client.UseBestLogin("user", "password")
    client.SelectInbox()
    For Each uid As Long In client.GetAll()
        Dim mail As IMail = New MailBuilder() _
            .CreateFromEml(client.GetMessageByUID(uid))

        SaveAttachmentsTo(mail, @"c:\tmp")
    Next
    client.Close()
End Using

The following method traverses through all attachments. If regular attachment is found it is saved to specified folder. If email message is attached it parses it and saves all its attachments using recursion:

// C#

private void SaveAttachmentsTo(IMail mail, string folder)
{
    foreach (MimeData attachment in mail.Attachments)
    {
        if (attachment is IMailContainer)
        {
            IMail attachedMessage = ((IMailContainer) attachment).Message;
            SaveAttachmentsTo(attachedMessage, folder);
        }
        else
        {
            attachment.Save(
                Path.Combine(folder, attachment.SafeFileName));
        }
    }
}
' VB.NET version

Private Sub SaveAttachmentsTo(mail As IMail, folder As String)
    For Each attachment As MimeData In mail.Attachments
        If TypeOf attachment Is IMailContainer Then
            Dim attachedMessage As IMail = DirectCast(attachment, IMailContainer).Message
    	    SaveAttachmentsTo(attachedMessage, folder)
        Else
            attachment.Save( _
                Path.Combine(folder, attachment.SafeFileName))
        End If
    Next
End Sub

Tags:      

Questions?

Consider using our Q&A forum for asking questions.

3 Responses to “Process emails embedded as attachments”

  1. Oj_41 Says:

    I want to connect to gmail account and download email attachments.
    Using pop3 As New Pop3()
    pop3.Connect(“pop3.gmail.com”)
    pop3.UseBestLogin(“xyz@gmail.com”, “password”)

    I am getting the following error:
    Server Exception was unhandled. No such host is known

  2. Limilabs support Says:

    @Oj_41,

    Gmail’s pop3 server address is: pop.gmail.com
    You need to use SSL – use ConnectSSL method.

    Here you can find Gmail mail server addresses

  3. Oj_41 Says:

    Thank you Limilabs !!!!!!