TNEF Attachments Handling in Email Messages

TNEF (Transport Neutral Encapsulation Format) is a proprietary format used by Microsoft Outlook to encapsulate rich content in attachments - most commonly stored as winmail.dat. The Aspose.Email API allows you to read email messages that have TNEF attachments and modify the contents of the attachment. The email can then be saved as a normal email or to the same format, preserving TNEF attachments. This article shows different code samples for working with messages containing TNEF attachments. This article also shows how to create TNEF EML files from Outlook MSG files.

Read a Message with TNEF Attachment

The following code snippet shows you how to read a message preserving TNEF attachments.

// The path to the File directory.
string dataDir = RunExamples.GetDataDir_Email();

MsgLoadOptions options = new MsgLoadOptions();
options.PreserveTnefAttachments = true;
MailMessage eml = MailMessage.Load(dataDir + "EmbeddedImage1.msg", options);
foreach (Attachment attachment in eml.Attachments)
{
    Console.WriteLine(attachment.Name);
}

Read a Message without TNEF Attachment

The following code snippet shows you how to read a message without preserving TNEF attachments. Setting PreserveTnefAttachments to false is the default behavior: the TNEF container is decoded and its contents are exposed as regular attachments instead of a single winmail.dat file.

// The path to the File directory.
string dataDir = RunExamples.GetDataDir_Email();

MsgLoadOptions options = new MsgLoadOptions();
options.PreserveTnefAttachments = false;
MailMessage eml = MailMessage.Load(dataDir + "EmbeddedImage1.msg", options);
foreach (Attachment attachment in eml.Attachments)
{
    Console.WriteLine(attachment.Name);
}

Load and Save TNEF Attachments

With Aspose.Email for .NET, you can load TNEF attachments directly into a MapiAttachment object using a file path or stream, and then save the object to TNEF format. This enables the creation of winmail.dat files or preservation of Outlook-specific formatting in email workflows.

The API provides the following members in the MapiAttachment class:

Load TNEF Attachments

Save TNEF Attachments

The code sample below demonstrates how to extract a winmail.dat attachment from an email message, preserve it, and re-add it as an attachment to the message:

// message.eml contains a winmail.dat attachment, but by default, the attachment is not preserved.
var msg = MapiMessage.Load("message.eml");

// Save the attachment to TNEF format in a stream and load it back
var ms = new MemoryStream();
msg.Attachments[0].SaveToTnef(ms);

ms.Position = 0;
var fromTnefAttachment = MapiAttachment.LoadFromTnef(ms);
msg.Attachments.Add(fromTnefAttachment);

// The same can be done through a file
msg.Attachments[0].SaveToTnef("winmail.dat");

fromTnefAttachment = MapiAttachment.LoadFromTnef("winmail.dat");
msg.Attachments.Add(fromTnefAttachment);

Update Resources in TNEF Attachment

The following code snippet shows you how to update resources in a TNEF attachment and preserve TNEF format.

public static void TestUpdateResources(string dataDir)
{
    string fileName = dataDir + "tnefEML1.eml";
    string imgFileName = dataDir + "Untitled.jpg";
    string outFileName = dataDir + "UpdateTNEFAttachments_out.eml";
    MailMessage originalMailMessage = MailMessage.Load(fileName);
    UpdateResources(originalMailMessage, imgFileName);
    EmlSaveOptions emlSo = new EmlSaveOptions(MailMessageSaveType.EmlFormat);
    emlSo.FileCompatibilityMode = FileCompatibilityMode.PreserveTnefAttachments;
    originalMailMessage.Save(outFileName, emlSo);
}

private static void UpdateResources(MailMessage msg, string imgFileName)
{
    for (int i = 0; i < msg.Attachments.Count; i++)
    {
        if ((msg.Attachments[i].ContentType.MediaType == "image/png") || (msg.Attachments[i].ContentType.MediaType == "application/octet-stream" && Path.GetExtension(msg.Attachments[i].ContentType.Name) == ".jpg"))
        {
            msg.Attachments[i].ContentStream = new MemoryStream(File.ReadAllBytes(imgFileName));
        }
        else if ((msg.Attachments[i].ContentType.MediaType == "message/rfc822") || (msg.Attachments[i].ContentType.MediaType == "application/octet-stream" && Path.GetExtension(msg.Attachments[i].ContentType.Name) == ".msg"))
        {
            MemoryStream ms = new MemoryStream();
            msg.Attachments[i].Save(ms);
            ms.Position = 0;
            MailMessage embeddedMessage = MailMessage.Load(ms);
            UpdateResources(embeddedMessage, imgFileName);
            MemoryStream msProcessedEmbedded = new MemoryStream();
            embeddedMessage.Save(msProcessedEmbedded, SaveOptions.DefaultMsgUnicode);
            msProcessedEmbedded.Position = 0;
            msg.Attachments[i].ContentStream = msProcessedEmbedded;
        }
    }

    foreach (LinkedResource att in msg.LinkedResources)
    {
        if (att.ContentType.MediaType == "image/png")
            att.ContentStream = new MemoryStream(File.ReadAllBytes(imgFileName));
    }
}

Add Attachment to TNEF Message

The following code snippet shows you how to add new attachments to the main message containing TNEF.


string fileName = "MainMessage.eml";
string attachName = "s.png";
string outFileName = "test.eml";

MailMessage mailMessage = MailMessage.Load(fileName);
mailMessage.Attachments.Add(new Attachment(File.OpenRead(attachName), "s.png", "image/png"));

// The TNEF content of the original message is preserved via EmlSaveOptions
EmlSaveOptions emlSaveOptions = new EmlSaveOptions(MailMessageSaveType.EmlFormat)
{
    FileCompatibilityMode = FileCompatibilityMode.PreserveTnefAttachments
};
mailMessage.Save(outFileName, emlSaveOptions);

Creating TNEF EML from MSG

Outlook MSGs sometimes contain information such as tables and text styles that may get disturbed if these are converted to EML. Creating TNEF messages from such MSG files allows to retain the formatting and even send such messages via the email clients retaining the formatting. The MailConversionOptions.ConvertAsTnef property is used to achieve this. The following code snippet shows you how to create TNEF EML from MSG.

MapiMessage mapiMsg = MapiMessage.FromFile(dataDir + "Message.msg");

MailConversionOptions mco = new MailConversionOptions();

mco.ConvertAsTnef = true;

MailMessage message = mapiMsg.ToMailMessage(mco); 

Alternatively, a TNEF EML can be produced by loading the MSG file with the PreserveTnefAttachments option of the MsgLoadOptions class enabled, and then saving the result as EML.

// Loading the MSG with PreserveTnefAttachments will create the TNEF eml.
MsgLoadOptions options = new MsgLoadOptions();
options.PreserveTnefAttachments = true;

MailMessage eml = MailMessage.Load(msgFileName, options);
eml.Save(emlFileName, SaveOptions.DefaultEml);

Identify TNEF Format Messages

The following code snippet shows you how to detect if a message is TNEF.

MailMessage mail = MailMessage.Load(dataDir + "tnefEml1.eml");

bool isTnef = mail.OriginalIsTnef;

Console.WriteLine("Is input EML originally TNEF? {0}", isTnef.ToString());

Identify TNEF Format Attachments

The Attachment.IsTnef property allows to detect whether the message attachment is TNEF formatted message.

var eml = MailMessage.Load(fileName);

foreach (var attachment in eml.Attachments)
{
    Console.WriteLine($"Is Attachment TNEF?: {attachment.IsTnef}");
}