Ryan Loggerythm
Ryan Loggerythm

Reputation: 3314

how to replace MailItem in outlook c#

I'm writing a stand-alone program to copy multiple PSTs to a single, new PST. When there are duplicates of an email, I'd like just 1 copy, not all of them.

As it stands, my code is:

if (item is Outlook.MailItem)
{
    Outlook.MailItem i = item as Outlook.MailItem;
    Outlook.MailItem iCopy = i.Copy();
    iCopy.Move(targetMAPIFolder);
}

Outlook is able to produce the desired results manually by choosing: File > Open > Import > Import from another program or file > Outlook data file > Replace duplicates with items imported.

Thanks for your help!

Upvotes: 0

Views: 890

Answers (2)

Eugene Astafiev
Eugene Astafiev

Reputation: 49395

The Outlook object model doesn't provide any property or method for checking duplicates. You need to compare item's properties to decide whether you need to copy a particular item or not. I'd suggest using the Find/FindNext or Restrict methods of the Items class to find duplicates. Also you may consider using the AdvancedSearch method of the Application class. The key benefits of using the AdvancedSearch method in Outlook are:

  • The search is performed in another thread. You don’t need to run another thread manually since the AdvancedSearch method runs it automatically in the background.
  • Possibility to search for any item types: mail, appointment, calendar, notes etc. in any location, i.e. beyond the scope of a certain folder. The Restrict and Find/FindNext methods can be applied to a particular Items collection (see the Items property of the Folder class in Outlook).
  • Full support for DASL queries (custom properties can be used for searching too). You can read more about this in the Filtering article in MSDN. To improve the search performance, Instant Search keywords can be used if Instant Search is enabled for the store (see the IsInstantSearchEnabled property of the Store class).
  • Finally, you can stop the search process at any moment using the Stop method of the Search class.

You can read more about these methods in the following articles:

Don't use the following code:

var duplicateItem = (
   from email in
   emailFolder.Items.OfType<MailItem>()

It will be very slow...

Upvotes: 2

DotNetHitMan
DotNetHitMan

Reputation: 951

You main problem here is how to determine what is a duplicate. If you were moving them within a single .PST you could compare the MailItem.Id property as this is unique in a single PST. As your moving from one pst to another you probably want to review which properties you deem as 'unique' on the mail item and compare them. (You could even use a hash value if you wanted). As an example -

var hash = String.Format("{0}{1}{2}{3}", item.To, item.From, item.CC, item.Subject, item.Body).GetHashCode();

Should give you a hash value to compare against the existing items in your target PST.

Or simply just compare the properties you deem would show a duplicate

Example -

private bool CheckIsDuplicate(MailItem item)
{
    //load the target pst
    Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
   Microsoft.Office.Interop.Outlook.NameSpace outlookNs = app.GetNamespace("MAPI");
   outlookNs.AddStore(@"D:\pst\Test.pst");
   Microsoft.Office.Interop.Outlook.MAPIFolder emailFolder = outlookNs.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderSentMail);

   //check for your mail item in the repository
   var duplicateItem = (
       from email in
       emailFolder.Items.OfType<MailItem>()
       where //here you could try a number of things a hash value of the properties or try using the item.I
       email.SenderName == item.SenderName &&
       email.To == item.To &&
       email.Subject == item.Subject &&
       email.Body == item.Body
       select email
           ).FirstOrDefault();

       return duplicateItem != null;
}

Upvotes: 1

Related Questions