Save mail to msg file using EWS API

Solution 1:

If you are happy to save into the .eml format instead, it can be done very easily just using EWS and no third party libraries. The .eml file will contain all the same information and can be opened by Outlook in the same way as .msg (and also by other programs).

message.Load(new PropertySet(ItemSchema.MimeContent));

MimeContent mc = message.MimeContent;
FileStream fs = new FileStream("c:\test.eml", FileMode.Create);

fs.Write(mc.Content, 0, mc.Content.Length);
fs.Close();

Cleaned up code:

message.Load(new PropertySet(ItemSchema.MimeContent));
var mimeContent = message.MimeContent;

using (var fileStream = new FileStream(@"C:\Test.eml", FileMode.Create))
{
    fileStream.Write(mimeContent.Content, 0, mimeContent.Content.Length);
}

Solution 2:

There is no native support for MSG files using EWS. It's strictly an Outlook format.

The MSG spec is published at http://msdn.microsoft.com/en-us/library/cc463912%28EXCHG.80%29.aspx. It's a little complicated to understand, but do-able. You would need to pull down all of the properties for the message and then serialize it into an OLE structured file format. It's not an easy task.

In the end, you are probably better off going with a 3rd party library otherwise it might be a big task to accomplish.

Solution 3:

You can easily access the MIME contents of the message through message.MimeContent and save the message as an EML file. The latest (2013 and 2016) versions of Outlook will be able to open EML files directly.

message.Load(new PropertySet(ItemSchema.MimeContent));
MimeContent mimcon = message.MimeContent;
FileStream fStream = new FileStream("c:\test.eml", FileMode.Create);
fStream.Write(mimcon.Content, 0, mimcon.Content.Length);
fStream.Close();

If you still need to convert to the MSG format, you have a few options:

  1. MSG file format is documented - it is an OLE store (IStorage) file. See https://msdn.microsoft.com/en-us/library/cc463912(v=exchg.80).aspx

  2. Use a third party MSG file wrapper, such as the one from Independentsoft: http://www.independentsoft.de/msg/index.html. Setting all properties that Outlook expects can be challenging.

  3. Convert EML file to MSG directly using Redemption:

    set Session = CreateObject("Redemption.RDOSession") set Msg = Session.CreateMessageFromMsgFile("c:\test.msg") Msg.Import("c:\test.eml", 1024) Msg.Save

  4. Keep in mind that MIME won't preserve all MAPI specific properties. You can use the Fast Transfer Stream (FTS) format used by the ExportItems EWS operation (which, just like the MSG format, preserves most MAPI properties). The FTS data can then be converted (without any loss of fidelity) to the MSG format using Redemption (RDOSession.CreateMessageFromMsgFile / RDOMail.Import(..., olFTS) / RDOMail.Save)

    RDOSession session = new RDOSession(); RDOMail msg = session.CreateMessageFromMsgFile(@"c:\temp\test.msg"); msg.Import(@"c:\temp\test.fts", rdoSaveAsType.olFTS); msg.Save();

Solution 4:

This suggestion was posted as a comment by @mack, but I think it deserves its own place as an answer, if for no other reason than formatting and readability of answers vs. comments.

using (FileStream fileStream = 
    File.Open(@"C:\message.eml", FileMode.Create, FileAccess.Write)) 
{ 
    message.Load(new PropertySet(ItemSchema.MimeContent)); 
    MimeContent mc = message.MimeContent; 
    fileStream.Write(mc.Content, 0, mc.Content.Length); 
}