none
Find SentItems folders from all mailboxes in Outlook 2007, VSTO and C# RRS feed

  • Question

  • Hi,

    we are trying to get all "sent items" folders from all mailboxes in Outlook 2007.

    Is there an easy way to achieve this?

    In Outlook 2010 there is the possibility to fetch the folder with store.GetDefaultFolder()

    In Outlook 2007 you can get the folder with Session.GetDefaultFolder() but unfortunately for other mailboxes than the default one there is no such method?

    In Outlook 2007 the only possibility I could find is enumerating through all folders in Application.Session.Folders and then enumerating through all folders in each of the root folders and looking for a name "sent items" or "Gesendete Elemente" in german.

    The major problem with this approach is that it isn't culture independent.

    Another problem is that it will take a while if you have many mailboxes with many folders like e.g. Offline mailboxes or archives etc.

    Is there any better approach to get this done with Outlook 2007 than to enumerate all folders?

    Thank you


    Regards Mark

    Wednesday, November 27, 2013 3:21 PM

Answers

  • Hi Wompi,

    The Namespace.GetSharedDefaultFolder method will not help you.

    Instead, you need to iterate via all stores and find the Sent Mail folder. Please pay a special attention to the fact that the folder name depends on the language an end user set on the PC (i.e. the folder name can be localized). That is why you can't rely on the name. Instead you need to use the EntryID property of the Folder class to find the required folder in a store. I have prepared a sample code which is works like a charm on my Outlook 2007:

    private IEnumerable<Outlook.Folder> GetListOfSentMailFolders()
    {
       string propertyName = "http://schemas.microsoft.com/mapi/proptag/0x35E40102";
       List<Outlook.Folder> sentMailFolders = new List<Outlook.Folder>();
       Outlook.NameSpace ns = OutlookApp.GetNamespace("MAPI");
       Outlook.Stores stores = ns.Stores;
       for (int i = 1; i <= stores.Count; i++)
       {
           Outlook.Store store = stores[i];
           Outlook.Folder rootFlder = store.GetRootFolder() as Outlook.Folder;
           Outlook.Folders folders = rootFlder.Folders;
    
           Outlook.PropertyAccessor propAcc = store.PropertyAccessor;
           object entry = propAcc.GetProperty(propertyName);
           string sentMailEntryID = propAcc.BinaryToString(entry);
           if (!string.IsNullOrEmpty(sentMailEntryID))
           {
              for (int j = 1; j <= folders.Count; j++)
              {
                  Outlook.Folder sentFolder = folders[j] as Outlook.Folder;
                  if (sentFolder.EntryID == sentMailEntryID)
                      sentMailFolders.Add(sentFolder);
                  else
                      Marshal.ReleaseComObject(sentFolder);
               }
           }
    
           Marshal.ReleaseComObject(propAcc);
           Marshal.ReleaseComObject(folders);
           Marshal.ReleaseComObject(rootFlder);
           Marshal.ReleaseComObject(store);
       }
       Marshal.ReleaseComObject(stores);
       Marshal.ReleaseComObject(ns);
    
       return sentMailFolders;
    }
    As you may see, there is no trivial way for getting the job done in case of Outlook 2007 ;)

    Thursday, November 28, 2013 1:18 PM

All replies

  • Use Namespace,GetSharedDefaultFolder

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

    Wednesday, November 27, 2013 3:39 PM
  • Hi Dmitry,


    thank you for your answer.

    I already had seen the GetSharedDefaultFolder but didn't know what to put for the recipient argument.

    I tried the following code but it always throws an ArgumentException with "One or more parameter values are not valid"

    var recipient = Application.Session.CreateRecipient(mailAddress);
    
    recipient.Resolve();
    
    var sharedFolder = Application.Session.GetSharedDefaultFolder(recipient, Outlook.OlDefaultFolders.olFolderSentMail);
    The recipient is valid and resolved. The mailAddress is the mail address of my default exchange account in outlook. I also tried the mail address from my second account (a hotmail account) which I have in my outlook profile but it always throws the exception.

    Is this the right way to get the recipient for the function or is there another possibility.

    Thank you.


    Regards Mark

    Thursday, November 28, 2013 8:23 AM
  • Hi Wompi,

    The Namespace.GetSharedDefaultFolder method will not help you.

    Instead, you need to iterate via all stores and find the Sent Mail folder. Please pay a special attention to the fact that the folder name depends on the language an end user set on the PC (i.e. the folder name can be localized). That is why you can't rely on the name. Instead you need to use the EntryID property of the Folder class to find the required folder in a store. I have prepared a sample code which is works like a charm on my Outlook 2007:

    private IEnumerable<Outlook.Folder> GetListOfSentMailFolders()
    {
       string propertyName = "http://schemas.microsoft.com/mapi/proptag/0x35E40102";
       List<Outlook.Folder> sentMailFolders = new List<Outlook.Folder>();
       Outlook.NameSpace ns = OutlookApp.GetNamespace("MAPI");
       Outlook.Stores stores = ns.Stores;
       for (int i = 1; i <= stores.Count; i++)
       {
           Outlook.Store store = stores[i];
           Outlook.Folder rootFlder = store.GetRootFolder() as Outlook.Folder;
           Outlook.Folders folders = rootFlder.Folders;
    
           Outlook.PropertyAccessor propAcc = store.PropertyAccessor;
           object entry = propAcc.GetProperty(propertyName);
           string sentMailEntryID = propAcc.BinaryToString(entry);
           if (!string.IsNullOrEmpty(sentMailEntryID))
           {
              for (int j = 1; j <= folders.Count; j++)
              {
                  Outlook.Folder sentFolder = folders[j] as Outlook.Folder;
                  if (sentFolder.EntryID == sentMailEntryID)
                      sentMailFolders.Add(sentFolder);
                  else
                      Marshal.ReleaseComObject(sentFolder);
               }
           }
    
           Marshal.ReleaseComObject(propAcc);
           Marshal.ReleaseComObject(folders);
           Marshal.ReleaseComObject(rootFlder);
           Marshal.ReleaseComObject(store);
       }
       Marshal.ReleaseComObject(stores);
       Marshal.ReleaseComObject(ns);
    
       return sentMailFolders;
    }
    As you may see, there is no trivial way for getting the job done in case of Outlook 2007 ;)

    Thursday, November 28, 2013 1:18 PM
  • Wow. Perfect.

    Thank you very much.

    This really works like a charm.

    I just added a try and catch because if you have e.g. an archive file without a sent items folder then the GetProperty() throws an exception.

    Thanky you :)


    Regards Mark

    Thursday, November 28, 2013 1:54 PM