none
How to copy a MailItem to a specified Folder? RRS feed

  • Question

  • I'm now developing an add-in for Outlook 2007.

    The functionality which I'm currently developing is automatically filing new mail received/sent by Outlook into different folders by mail's subject. But also I need to keep the original copy in the Inbox/SentItems folder.

    Now I'm using Items.ItemAdd event to monitor the Inbox/SentItems folder, then call the MailItem.Copy() and MailItem.Move(DestFolder As MAPIFolder) to copy the mail into corresponding folder.

    However, I found that my method is completely wrong. When MailItem.Copy() is executed, the Items.ItemAdd event is fired again before the add-in move the mail. Then the event handler will be executed again and again.

    There'is no method in library to let me copy a MailItem to a specified Folder. Copy and Move is the simplest way I can find. Should I change to use other events like NewItemEx and ItemSend, or use another way to copy the mail to the destination?

    Does anyone can suggest me a correct way to solve this situation?

    Many thanks.

    Tuesday, June 19, 2012 7:01 AM

Answers

  • As far as I know, ItemAdd() and other such events are not re-entrant. If you're in the midst of processing such an event it won't fire again with that event handler until you exit the original handler. If you take too long to process the original event, or more than about 16 items at once are added to the folder's Items collection, the event won't fire at all.
     
    The flag is a good idea, but I usually implement it as an entry in a list using the EntryID for the item being processed. I add the EntryID to the list when processing the item, then if the event fires again I can check the EntryID to see if it's in the list. After moving the item the list can be cleaned for that EntryID.
     
    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "DamianD" <=?utf-8?B?RGFtaWFuRA==?=> wrote in message news:0f21f46b-a2f3-4885-a431-6819746bd48b...

    go back to original itemadd on sent items and inbox folder

    but inside itemadd event handler set a boolean flag (your class level variable) that you are already in itemadd event and inbokve your copy and move, on exiting itemadd handler, clear that flag. Now in the beginning of itemadd routine check of this flag is set, if so, return. Something like this:

    bool _processingEvent = false;

    private void ItemAdd(Object item)

    {

    if(_processingEvent) return;

    try

    {

    _processingEvent = true;

    var newone = Item.Copy();

    newOne.move(folder);

    }

    finally

    {

    _processingEvent = false;

    }

    }


    Ken Slovak MVP - Outlook
    • Marked as answer by Eranyang Wednesday, June 20, 2012 4:01 AM
    Tuesday, June 19, 2012 2:14 PM
    Moderator

All replies

  • I have tried Application.ItemSend event instead of ItemAdd, the repeated of firing event handler has been solved, but there's another problem:

    By using ItemSend event, the add-in will do MailItem.Copy() during sending this mail. The copy of this mail is still kept in Outbox without sending, then moved into the designated folder. The problem is that the MailItem has not been sent, so the receiver will not be displayed in the explorer view.

    I also tried call MailItem.Send() before MailItem.Copy(), but it said I cannot send a mail already in sending progress.
    • Edited by Eranyang Tuesday, June 19, 2012 7:23 AM
    Tuesday, June 19, 2012 7:22 AM
  • go back to original itemadd on sent items and inbox folder

    but inside itemadd event handler set a boolean flag (your class level variable) that you are already in itemadd event and inbokve your copy and move, on exiting itemadd handler, clear that flag. Now in the beginning of itemadd routine check of this flag is set, if so, return. Something like this:

    bool _processingEvent = false;

    private void ItemAdd(Object item)

    {

    if(_processingEvent) return;

    try

    {

    _processingEvent = true;

    var newone = Item.Copy();

    newOne.move(folder);

    }

    finally

    {

    _processingEvent = false;

    }

    }

    Tuesday, June 19, 2012 10:42 AM
  • As far as I know, ItemAdd() and other such events are not re-entrant. If you're in the midst of processing such an event it won't fire again with that event handler until you exit the original handler. If you take too long to process the original event, or more than about 16 items at once are added to the folder's Items collection, the event won't fire at all.
     
    The flag is a good idea, but I usually implement it as an entry in a list using the EntryID for the item being processed. I add the EntryID to the list when processing the item, then if the event fires again I can check the EntryID to see if it's in the list. After moving the item the list can be cleaned for that EntryID.
     
    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "DamianD" <=?utf-8?B?RGFtaWFuRA==?=> wrote in message news:0f21f46b-a2f3-4885-a431-6819746bd48b...

    go back to original itemadd on sent items and inbox folder

    but inside itemadd event handler set a boolean flag (your class level variable) that you are already in itemadd event and inbokve your copy and move, on exiting itemadd handler, clear that flag. Now in the beginning of itemadd routine check of this flag is set, if so, return. Something like this:

    bool _processingEvent = false;

    private void ItemAdd(Object item)

    {

    if(_processingEvent) return;

    try

    {

    _processingEvent = true;

    var newone = Item.Copy();

    newOne.move(folder);

    }

    finally

    {

    _processingEvent = false;

    }

    }


    Ken Slovak MVP - Outlook
    • Marked as answer by Eranyang Wednesday, June 20, 2012 4:01 AM
    Tuesday, June 19, 2012 2:14 PM
    Moderator
  • If using Redemption is an option, you can call RDOMail.CopyTo(RDOFolder).

    Something along the lines

    set Session = CreateObject("Redemption.RDOSession")
    Session.MAPIOBJECT = Application.Session.MAPIOBJECT
    set sourceMsg = Session.GetRDOObjectFromOutlookObject(YourMailItem)
    set destFolder = Session.GetRDOObjectFromOutlookObject(YourOutlookFolder)
    sourceMsg.CopyTo(destFolder)


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.3 is now available!

    Tuesday, June 19, 2012 5:52 PM
  • Thank you, Ken.

    The ItemAdd event just happened if I didn't move the copy of the mail. The event wouldn't be fired after successful moving.


    Wednesday, June 20, 2012 4:01 AM
  • Thanks for you, DamianD.

    However I think using a flag will block new incoming items' copy/move during processing current event.

    Wednesday, June 20, 2012 4:03 AM
  • outlook API is STA based, so there is no way something new will appear when your code runs in main UI thread. Everything will 'freeze' and wait untill your code finish, so no worries here.
    Wednesday, June 20, 2012 7:42 AM