none
Store.GetDefaultFolder() throws AccessViolationException and crashes Outlook 2007 RRS feed

  • Question

  • I have a simple requirement for an outlook addin. which monitors for the sent emails and wrote a log about the email sent.

    I used the MAPI folder's ItemAdd event.

    var folder = Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);

    folder.Items.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(ThisAddIn_ItemAdd);

    Also I refer the folder.Items in a global variable so that it wont get garbage collected. That works very well for both office 2007 and 2010.

    if multiple data files configured, I need to monitor for all the sent item's folders in all data files. for that I used the following code,

    public partial class ThisAddIn
    {
        List<Outlook.Items> _sentItemFoldersFromStores = new List<Outlook.Items>();
    
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
    
            foreach (Outlook.Store store in Application.Session.Stores)
            {
                Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
    
                var folder = store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
    
                if (folder != null)
                {
                    // Stores the items object to a collection for persistant reference. Otherwise the the event handler wont get fired ( becuase of GC de-allocate the event ).
                    _sentItemFoldersFromStores.Add(folder.Items);
                    _sentItemFoldersFromStores[_sentItemFoldersFromStores.Count - 1].ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(ThisAddIn_ItemAdd);
                }
    
            }
        }
    
        void ThisAddIn_ItemAdd(object Item)
        {
            System.Windows.Forms.MessageBox.Show("Item Added to sent folder -" + ((Outlook.MailItem)Item).Subject);
        }
    
        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }
    
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }
            
    }

    The code works very well for Office 2010. for the Office 2007 I got an AccessviolationException in the store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail); .

    Details

    ---------

    I created the project using, VS.NET 2010 -> Outlook 2010 Addin.

    Outlook version I tested- Outlook 2007 SP3

    Is there any way to fix that problem?

    Thanks & Regards

    Prakash

    Friday, April 20, 2012 11:34 AM

Answers

  • why is there free floating line

    Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);

    please remove it. Also i would advice to code against lowest common PIA version, which means 2007 and not use 2010 and hope for the best.

    • Marked as answer by prakashguru1 Friday, April 20, 2012 1:57 PM
    Friday, April 20, 2012 12:40 PM
  • modified version to get the default sent item,

    string PR_IPM_SENTMAIL_ENTRYID = @"http://schemas.microsoft.com/mapi/proptag/0x35E40102";
    
    foreach (OutlookX.Store store in Application.Session.Stores)
    {
    try
    {
        byte[] binaryEntryID = (byte[])store.PropertyAccessor.GetProperty(PR_IPM_SENTMAIL_ENTRYID);
    
        var sentItemFoldersEntryId = binaryEntryID.Aggregate(new StringBuilder(), 
            (a, b) =>
            {
                var tempString = b.ToString("X");
    
                a.Append(tempString.Length == 1 ? "0" + tempString : tempString);
    
                return a;
            }, a => a.ToString());
    
    
        var folder = Application.Session.GetFolderFromID(sentItemFoldersEntryId);
    
        if (folder != null)
        {
            _sentItemFoldersFromStores.Add(folder.Items);
    
            _sentItemFoldersFromStores[_sentItemFoldersFromStores.Count - 1].ItemAdd += new OutlookX.ItemsEvents_ItemAddEventHandler(_sentItems_ItemAdd);
        }
        else
        {
            Logger.Write(" Store : [" + store.DisplayName + "] - Does not have sent items folder.");
        }
    }
    catch (Exception ex)
    {
        //The store does not contain a sent items folder.
        Logger.Write(" Store : [" + store.DisplayName + "] - Does not have sent items folder." + ex.Message);
    }

    • Marked as answer by prakashguru1 Wednesday, April 25, 2012 7:39 AM
    Wednesday, April 25, 2012 7:39 AM

All replies

  • why is there free floating line

    Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);

    please remove it. Also i would advice to code against lowest common PIA version, which means 2007 and not use 2010 and hope for the best.

    • Marked as answer by prakashguru1 Friday, April 20, 2012 1:57 PM
    Friday, April 20, 2012 12:40 PM
  • thank you very much for your reply damian

    I created a new project using office 2007 template and try to compile the code.

    I got the error "'Microsoft.Office.Interop.Outlook.Store' does not contain a definition for 'GetDefaultFolder'". 

    The Outlook 2007 interop dll (Microsoft.Office.Interop.Outlook.dll) does not have "GetDefaultFolder" method in the Store class. 

    I changed the code to use the folder's collection of the namespace. that worked in both. 

    modified code, 

    foreach (Outlook.Folder folder in Application.Session.Folders)
    {
        var sentfolder = folder.Folders.Cast<Outlook.Folder>().Where(c => c.Name == "Sent Items").SingleOrDefault();
        if (sentfolder != null)
        {
            // Stores the items object to a collection for persistant reference. Otherwise the the event handler wont get fired ( becuase of GC de-allocate the event ).
            _sentItemFoldersFromStores.Add(sentfolder.Items);
            _sentItemFoldersFromStores[_sentItemFoldersFromStores.Count - 1].ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(ThisAddIn_ItemAdd);
        }
        else
        {
            MessageBox.Show("No Sent Items folder in - " + folder.Name);
        }
    }

    the new code worked in both the office versions.

    thank you very much for pointing the problem damiand.


    • Marked as answer by prakashguru1 Friday, April 20, 2012 1:57 PM
    • Unmarked as answer by prakashguru1 Wednesday, April 25, 2012 7:40 AM
    Friday, April 20, 2012 1:57 PM
  • modified version to get the default sent item,

    string PR_IPM_SENTMAIL_ENTRYID = @"http://schemas.microsoft.com/mapi/proptag/0x35E40102";
    
    foreach (OutlookX.Store store in Application.Session.Stores)
    {
    try
    {
        byte[] binaryEntryID = (byte[])store.PropertyAccessor.GetProperty(PR_IPM_SENTMAIL_ENTRYID);
    
        var sentItemFoldersEntryId = binaryEntryID.Aggregate(new StringBuilder(), 
            (a, b) =>
            {
                var tempString = b.ToString("X");
    
                a.Append(tempString.Length == 1 ? "0" + tempString : tempString);
    
                return a;
            }, a => a.ToString());
    
    
        var folder = Application.Session.GetFolderFromID(sentItemFoldersEntryId);
    
        if (folder != null)
        {
            _sentItemFoldersFromStores.Add(folder.Items);
    
            _sentItemFoldersFromStores[_sentItemFoldersFromStores.Count - 1].ItemAdd += new OutlookX.ItemsEvents_ItemAddEventHandler(_sentItems_ItemAdd);
        }
        else
        {
            Logger.Write(" Store : [" + store.DisplayName + "] - Does not have sent items folder.");
        }
    }
    catch (Exception ex)
    {
        //The store does not contain a sent items folder.
        Logger.Write(" Store : [" + store.DisplayName + "] - Does not have sent items folder." + ex.Message);
    }

    • Marked as answer by prakashguru1 Wednesday, April 25, 2012 7:39 AM
    Wednesday, April 25, 2012 7:39 AM
  • please notice that propertyaccessor alsready has methods for converting binary to string.
    Wednesday, April 25, 2012 9:55 AM