Martijn's blog - E-Commerce, EAI, BizTalk and .NET

2006/12/26

Outlook: Recovering e-mail messages from attachments

Recently, I was what I thought to be dragging e-mail from my Inbox into my Personal Folders. Outlook warned me that the process could take some time due to the amount of messages selected, but I went ahead with the move. After a while, Outlook popped up a freshly created e-mail message containing my 1000+ e-mail messages!

The new e-mail was about 85MB and the original message were gone from my inbox... I really wanted those e-mails in my Personal Folders. However, Outlook programming is something I've always shied away from. After some experimenting, I discovered what I wanted couldn't be easily done using Outlook APIs...

I wanted to:
  1. Open the e-mail message containing the attached 1000+ 'backups'
  2. Iterate the attachments
  3. Save the attachments as e-mails into my Personal Folders box
After a lot of headache, I discovered Redemption (see http://www.dimastr.com/redemption/). Redemption provides interop between .NET and the Extended MAPI. Using redemption, I finally succeeded in achieving my goal. Just in case someone else outthere is as silly as I am, here's how I did it:
// To use this namespace you must set a
// reference to the Microsoft Outlook 11.0
// COM server. 
using Microsoft.Office.Interop.Outlook;
using OutLookApp = Microsoft.Office.Interop.Outlook.Application;
using System.IO;
using rd = Redemption;

ApplicationClass outLookApp = new ApplicationClass();
NameSpace outlookNS = outlookApp.GetNamespace("MAPI");

MailItem attachmentsItem = (MailItem)outlookNS.GetItemFromID(messageId, null);

// left out for clarity: find the Personal Folders->Inbox folder

rd.MAPIUtils utils = new rd.MAPIUtils();
utils.MAPIOBJECT = outlookNS.MAPIOBJECT;

foreach (Attachment a in attachmentsItem.Attachments)
{
 string attachmentFile = Path.GetTempFileName();
 a.SaveAsFile(attachmentFile);

 MailItem underlyingItem = 
  (MailItem)personalFolder.Items.Add(OlItemType.olMailItem);

 rd.MessageItem neww = 
  utils.GetItemFromMsgFile(attachmentFile, false);

 underlyingItem.Save();
 
 MailItem placedItem = 
  (MailItem)underlyingItem.Move(personalFolder);

 neww.CopyTo(placedItem);
}

This code misses all kinds of nice sanity checks, like whether the attachment actually is a MSG file, etc. It sufficed for my scenario and I now have the e-mails back. FYI :-D

7 Comments:

Post a Comment

<< Home