none
How to examine every incoming email of all folders RRS feed

  • Question

  • My outlook hosts multiple emails, hence multiple folders.   I am trying to inspect every incoming email by modifying an official example:

            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                //The only supported name space type is "MAPI". The GetNameSpace method is functionally equivalent to the Session property.
                outlookNameSpace = this.Application.GetNamespace("MAPI");
    
                foreach (Folder folder in outlookNameSpace.Folders)
                {
                    if (folder.DefaultItemType == OlItemType.olMailItem)
                    {
                        Debug.WriteLine("Folder: " + folder.Name);
                        items = folder.Items;
                        items.ItemAdd +=
                            new Outlook.ItemsEvents_ItemAddEventHandler(items_ItemAdd);
                    }
                }
            }
    
            void items_ItemAdd(object Item)
            {
                Debug.WriteLine("---------- items_ItemAdd has been called----------------------");
      
            }
    

    items_ItemAdd  is never called despite the following code outputs all correct email addresses:

     Debug.WriteLine("Folder: " + folder.Name);

    Could anyone shed some light on this?


    Hong

    Sunday, November 24, 2019 4:44 PM

Answers

  • Namespace.Folders collection contains top level folders of each store in the profile. Those folders do not contain any items.

    If you want all Inbox folders, loop through all stores in the Namespace.Stores collection and for each store call Store.GetDefaultFolder(olFolderInbox).

    But the code above should work fine for the primary store in the profile.


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


    Sunday, November 24, 2019 5:36 PM

All replies

  • items in your code is a single variable, and you overwrite its value on each iteration. You need to create a wrapper class that will store the Items object as a property and provide the event handler, You can then create a list (List<MyItemWrapper>) and store your wrappers there - this will ensure that each Items collection is alive and can raise events.

    That being said, opening each and every folder and tracking their events is a bad idea.


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

    Sunday, November 24, 2019 4:59 PM
  • Thank you.

    What would you suggest to inspect each incoming email?

    I am just sick and tired of spam emails with HTML format which inspection is not supported by Outlook filters. 


    Hong

    Sunday, November 24, 2019 5:08 PM
  • Why are you setting up the event handlers on *all* folders instead of just the Inbox?

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

    Sunday, November 24, 2019 5:17 PM
  • Perhaps I have misunderstood the meaning of "Inbox" for add-in.   Each folder corresponds to an email address (e.g. myid@domainA.net, myid@domainB.com, myid@domainC.org...) and there is an Inbox in each folder in my Outlook.

    I am using the aforementioned code because the code from the official sample failed to catch any emails except those for myid@msn.com:

    Outlook.NameSpace outlookNameSpace;
    Outlook.MAPIFolder inbox;
    Outlook.Items items;
    
    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        outlookNameSpace = this.Application.GetNamespace("MAPI");
        inbox = outlookNameSpace.GetDefaultFolder(
                Microsoft.Office.Interop.Outlook.
                OlDefaultFolders.olFolderInbox);
    
        items = inbox.Items;
        items.ItemAdd +=
            new Outlook.ItemsEvents_ItemAddEventHandler(items_ItemAdd);
    }
    
    void items_ItemAdd(object Item)
    {
           Debug.WriteLine("---------- items_ItemAdd has been called----------------------");
    }


    Hong

    Sunday, November 24, 2019 5:30 PM
  • Namespace.Folders collection contains top level folders of each store in the profile. Those folders do not contain any items.

    If you want all Inbox folders, loop through all stores in the Namespace.Stores collection and for each store call Store.GetDefaultFolder(olFolderInbox).

    But the code above should work fine for the primary store in the profile.


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


    Sunday, November 24, 2019 5:36 PM
  • It works!  Thank you.

    However, I do not understand why it works only when Outlook starts.   Subsequent incoming emails do not trigger items_ItemAdd().  My intention is inspecting every email all the time. 


    Hong

    Sunday, November 24, 2019 6:16 PM
  • I am not sure what you mean - do you mean you start your code when Outlook is *not* running? In that case it probably won't download any new emails until you open its UI.

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

    Sunday, November 24, 2019 6:46 PM
  • Yes, it is what I meant:

    1. Outlook is closed.
    2. Start the add-in from VS and this opens OL.
    3. OL immediately starts downloading email as usual, and every email is inspected by the add-in as expected. 
    4. A few minutes later, OL receives more emails, but none is inspected by the add-in.

    However, everything appears to work well now after I added a dummy List<Items> listItems:

            Outlook.NameSpace outlookNameSpace;
    
            List<Items> listItems = new List<Items>();
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                //The only supported name space type is "MAPI". The GetNameSpace method is functionally equivalent to the Session property.
                outlookNameSpace = this.Application.GetNamespace("MAPI");
                foreach (Store store in outlookNameSpace.Stores)
                {
    
                    MAPIFolder mapifolderInbox = store.GetDefaultFolder(
                        Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
                    Debug.WriteLine("Folder: " + mapifolderInbox.Name);
                    Items items = mapifolderInbox.Items;
                    items.ItemAdd +=
                        new Outlook.ItemsEvents_ItemAddEventHandler(items_ItemAdd);
                    
                    //Hope to keep items from garbage collection.
                    listItems.Add(items);
                }
            }
    
            void items_ItemAdd(object Item)
            {
                Debug.WriteLine("---------- items_ItemAdd has been called----------------------");
    
                Outlook.MailItem mail = (Outlook.MailItem)Item;
                if (Item != null)
                {
                    Debug.WriteLine("----------" + mail.Subject + "----------------------");
                }
    
            }
    


    Hong

    Sunday, November 24, 2019 7:15 PM
  • Do you define items variable on the global (class) level?

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

    Sunday, November 24, 2019 7:43 PM
  • No, it is defined locally.  I originally thought the references of the event handlers would prevent them from garbage collection. Now, I use the class level listItems to hold them.

    This is my first add-in in quite a few years.  It seems that Microsoft is deprecating this type of add-ins.  Though I make this primarily for my own use. I would love to put it somewhere in case it is useful for others. 


    Hong

    Sunday, November 24, 2019 8:52 PM