Posts Tagged ‘eml’

Reading Outlook .msg file format in .NET

Monday, October 14th, 2013

Files containing the .msg file extension are most commonly created by or saved from within one of the Microsoft Outlook email applications.

The MSG file contains information about a saved email file including the date of the message, the subject, who sent it, who received it and the contents of the email associated with the file. If attachments ares included with an email, that information will also be saved within the associated MSG file.

MsgConverter , than can be used to read .msg files, is written in pure .NET, it does not require registration or any other components or libraries (including Outlook).

The following code snippet reads .msg file in .NET and access its most common properties, such as subject, sender and attachments.

// C#

using (MsgConverter converter = new MsgConverter(@"c:\outlook1.msg"))
{
    if (converter.Type == MsgType.Note)
    {
        IMail email = converter.CreateMessage();

        Console.WriteLine("Subject: {0}", email.Subject);
        Console.WriteLine("Sender name: {0}", email.Sender.Name);
        Console.WriteLine("Sender address: {0}", email.Sender.Address);

        Console.WriteLine("Attachments: {0}", email.Attachments.Count);
        foreach (MimeData attachment in email.Attachments)
        {
            attachment.Save(@"c:\" + attachment.SafeFileName);
        }
    }
}
' VB.NET

Using converter As New MsgConverter("c:\outlook1.msg")
    If converter.Type = MsgType.Note Then
        Dim email As IMail = converter.CreateMessage()

        Console.WriteLine("Subject: {0}", email.Subject)
        Console.WriteLine("Sender name: {0}", email.Sender.Name)
        Console.WriteLine("Sender address: {0}", email.Sender.Address)
        
        Console.WriteLine("Attachments: {0}", email.Attachments.Count)
        For Each attachment As MimeData In email.Attachments
            attachment.Save("c:\" + attachment.SafeFileName)
        Next

    End If
End Using

You can read more on how to access To, Cc, Bcc fields.

Save raw eml file using IMAP and POP3

Wednesday, December 7th, 2011

There are times that you need to save raw email data in eml format.

This tutorial shows how to use Mail.dll POP3 and IMAP clients to achieve this goal.

Note that we don’t need to parse the emails, so we aren’t using MailBuilder class and IMail interface.

Samples provided use both POP3 and IMAP protocols and both C# and VB.NET.

Save email using IMAP:

The code below will search for all the emails with specified subject and write all these emails to your c: drive.

// C# code

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

    imap.SelectInbox();

    List<long> uids = imap.Search(
        Expression.Subject("email subject"));

    foreach (long uid in uids)
    {
        var eml = imap.GetMessageByUID(uid);
        string fileName = string.Format(@"c:\email_{0}.eml", uid);
        File.WriteAllBytes(fileName, eml);
    }
    imap.Close();
}
' VB.NET code

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

	imap.SelectInbox()

	Dim uids As List(Of Long) = imap.Search( _
		Expression.Subject("email subject"))

	For Each uid As Long In uids
		Dim eml = imap.GetMessageByUID(uid)
		Dim fileName As String = String.Format(@"c:\email_{0}.eml", uid)
		File.WriteAllBytes(fileName, eml)
	Next
	imap.Close()
End Using

Save email using POP3:

As POP3 protocol does not allow searching, the code below will write all emails to your c: drive. You can easily limit this to the specified uid.

// C# code

using (Pop3 pop3 = new Pop3())
{
    pop3.Connect("pop3.example.com");    // use ConnectSSL for SSL connection.
    pop3.UseBestLogin("user", "password");

    foreach (string uid in pop3.GetAll())
    {
        var eml = pop3.GetMessageByUID(uid));
        string fileName = string.Format(@"c:\email_{0}.eml", uid);
        File.WriteAllBytes(fileName, eml);
    }
    pop3.Close();
}
' VB.NET code

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

  For Each uid As String In pop3.GetAll()
		Dim eml = pop3.GetMessageByUID(uid)
		Dim fileName As String = String.Format("c:\email_{0}.eml", uid)
		File.WriteAllBytes(fileName, eml)
	Next
	pop3.Close()
End Using

You can download Mail.dll at: Mail.dll .NET email component

Process emails embedded as attachments

Tuesday, January 11th, 2011

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

I have problems parsing the message

Tuesday, January 4th, 2011

Mail.dll is a rock solid product, however most emails don’t follow RFC specifications rigorously. In the following few steps we’ll help you gather the information we need to make Mail.dll parser better.

If you have problems issuing IMAP, POP3, or SMTP command please go here.

Prerequisites

First please check if you have the latest version installed. You can always download the latest version of Mail.dll email component and release notes here.

Identify UID

Please identify unique id (UID) of the message you are having problems with.

Download

Next step is to download entire message and save it as raw eml file.
Note that you should not parse the email, so there is no need to use MailBuilder and IMail classes.

IMAP protocol

// C# code

long uid = 12345;

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

    byte[] eml = imap.GetMessageByUID(uid);
    string fileName = string.Format(@"c:\email_{0}.eml", uid);
    File.WriteAllBytes(fileName, eml);

    imap.Close();
}
' VB.NET code

Dim uid As Long = 12345

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

	Dim eml As Byte() = imap.GetMessageByUID(uid)
	Dim fileName As String = String.Format("c:\email_{0}.eml", uid)
	File.WriteAllBytes(fileName, eml))

	imap.Close()
End Using

POP3 protocol

// C# code

string uid = "12345";

using (Pop3 pop3 = new Pop3())
{
    pop3.Connect("pop3.example.com");    // or pop3.ConnectSSL("pop3.example.com"); 
    pop3.UseBestLogin("user", "password");

    byte[] eml = pop3.GetMessageByUID(uid));
    string fileName = string.Format(@"c:\email_{0}.eml", uid);
    File.WriteAllBytes(fileName, eml);

    pop3.Close();
}
' VB.NET code

Dim uid As String = "12345"

Using pop3 As New Pop3()
	pop3.Connect("pop3.example.com")	' or pop3.ConnectSSL("pop3.example.com")
	pop3.UseBestLogin("user", "password")

	Dim eml As Byte() = pop3.GetMessageByUID(uid)
	Dim fileName As String = String.Format("c:\email_{0}.eml", uid)
	File.WriteAllBytes(fileName, eml)

	pop3.Close()
End Using

Additional information

Please answer following questions:

  • What exception are you getting?
  • What is the exception stack trace?
  • What is the exception message?
  • What result you expect?
  • What result are you getting?
  • Which .NET Framework version are you using?
  • Is it console, windows forms, windows service or web application?
  • If it is possible please attach the source code you are using

Sending

Finally please zip the eml file and send it as a attachment (possibly zipped), along with all the answers to
.

Thank you!

Send raw data (*.eml file)

Monday, October 25th, 2010

This post describes how to send raw eml email data as email message using SMTP server.

In most cases you don’t need to send raw eml data.
Take a look at those topics, they may be better describing your needs:

*.eml extension is a standard extension used for storing email files. Eml file contains raw data received from POP3 or IMAP server. You can use GetMessageByUID on Pop3 or Imap class to obtain it. It can be also created using IMail.Render method:

MailBuilder builder = new MailBuilder();
builder.Subject = "Test";
builder.Text = "This is plain text message.";
builder.From.Add(new MailBox("alice@mail.com", "Alice"));
builder.To.Add(new MailBox("bob@mail.com", "Bob"));
IMail email = builder.Create();
byte[] eml = email.Render();

Eml file includes all attachments, visual elements, email body in text, HTML (if defined) formats and email headers (such as: from, to, subject, date and so on).

When sending email message using SMTP protocol you must fill three SmtpMail class properties:

  • From – FROM command dialogue
  • To – RCPT TO command in SMTP dialogue
  • RawEmlData – DATA command in SMTP dialogue

As you can see both ‘from address’ and ‘recipient’ are duplicated – they also appear in eml data as email From and To headers. SmtpMail has helper methods, such as CreateFromEmlFile or CreateFromEml that parse eml data and fill all properties required for SMTP communication.

// C# version

using Limilabs.Client.SMTP;

class Program
{
    static void Main(string[] args)
    {
        using (Smtp smtp = new Smtp())
        {
            smtp.Connect("server.company.com");
            smtp.UseBestLogin("user", "password");

            SmtpMail smtpMail = SmtpMail.CreateFromEmlFile(@"c:\email.eml");

            smtp.SendMessage(smtpMail);
            smtp.Close();
        }
    }
};
' VB.NET version

Imports Limilabs.Client.SMTP

Public Module Module1
    Public Sub Main(ByVal args As String())
        Using smtp As New Smtp()
            smtp.Connect("server.company.com")
            smtp.UseBestLogin("user", "password")

            Dim smtpMail As SmtpMail = smtpMail.CreateFromEmlFile("c:\email.eml")

            smtp.SendMessage(SmtpMail)
            smtp.Close()
        End Using
    End Sub
End Module