We've written an Outlook add-in that starts an action when an email has been sent. The action should only occur when a flag has been set during composing of the email. The flag is set by clicking on a toggle button. When the email is being send an event fires and we store the id of the email in a queue. If the mail appears in the sent folder an event should fire and if the same id is spotted in the queue then an action should happen.
Below I have two methods. Application_ItemSend will occur when the email is being send and in that method EnQueue is called on SentItemsQueue. The EnQueue method attaches an event to the Sent Items folder and when an item is added it should fire an event that will start our action.
This is all working fine when the email is being composed and send within Outlook. If we start an email from within an external program, like Word, then Application_ItemSend is executed but EMailFoundInSentItems (attached in EnQueue) is never triggered. Why is the event never triggered?
public partial class ThisAddIn {
void Application_ItemSend(object item, ref bool cancel)
{
try
{
Trace.TraceInformation("E-mail is being sent. Checking for archive flag.");
MailItem mail = item as MailItem;
bool? archive = mail.GetArchiveFlag();
if (archive == true)
{
Trace.TraceInformation("Archive flag was set, going to queue e-mail for archiving.");
this.SentItemsQueue.EnQueue(mail);
}
Marshal.ReleaseComObject(mail);
}
catch (System.Exception ex)
{
Trace.TraceError("An exception was thrown while trying to archive a sent mail item. Exception: {0}.", ex.ToString());
}
}
...
public class SentItemsArchiveQueue
{
public void EnQueue(MailItem mail)
{
// remove and re-add handler (remove first, so it's not registered twice)
mail.SaveSentMessageFolder.Items.ItemAdd -= new ItemsEvents_ItemAddEventHandler(EMailFoundInSentItems);
mail.SaveSentMessageFolder.Items.ItemAdd += new ItemsEvents_ItemAddEventHandler(EMailFoundInSentItems);
this.Queue.Add(mail.ConversationIndex);
Trace.TraceInformation("Queue ConversationIndex is {0}", mail.ConversationIndex);
}
...
The object that raises the events (Items collection) must be kept alive to be able to raise events. You are using multiple dot notation and as soon as an implicit variable created by the compiler goes out of scope and gets garbage collected, no events will be raised:
public class SentItemsArchiveQueue
{
private Items _items;
public void EnQueue(MailItem mail)
{
_items = mail.SaveSentMessageFolder.Items;
_items.ItemAdd += new ItemsEvents_ItemAddEventHandler(EMailFoundInSentItems);
this.Queue.Add(mail.ConversationIndex);
Trace.TraceInformation("Queue ConversationIndex is {0}", mail.ConversationIndex);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With