none
"The message you specified cannot be found" exception is thrown when new mail attachment is read. RRS feed

  • Question

  • I am first creating outlook rule during outlook start up event using below code:

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {

                      CreateRules(this.Application);

    this.Application.NewMailEx += new Outlook.ApplicationEvents_11_NewMailExEventHandler(Application_NewMailEx);  

    #region toolbar items
                    //RemoveMenubar();
                    selectExplorers = this.Application.Explorers;
                    selectExplorers.NewExplorer += new Outlook.ExplorersEvents_NewExplorerEventHandler(newExplorer_Event);
                    AddToolbar();
                    #endregion             

             }

    private void CreateRules(Microsoft.Office.Interop.Outlook.Application OutlookApp)
            {
                Outlook.NameSpace session = null;
                Outlook.Store store = null;
                Outlook.Rules rules = null;
                Outlook.MAPIFolder destinationFolder = null;
                Outlook.MAPIFolder rootFolder = null;
                Outlook.Folders rootFolderFolders = null;

                Outlook.Rule rule = null;
                Outlook.RuleConditions ruleConditions = null;
                Outlook.TextRuleCondition subjectTextRuleCondition = null;

                Outlook.RuleActions ruleActions = null;
                Outlook.MoveOrCopyRuleAction moveRuleAction = null;



                try
                {
                    session = OutlookApp.Session;
                    store = session.DefaultStore;
                    rules = store.GetRules();

                    if (!RuleExist(mRuleName, rules))
                    {
                        rootFolder = store.GetRootFolder();
                        destinationFolder = GetFolder(rootFolder.FolderPath + "\\" + mIncidentMailFolder, OutlookApp);

                        if (destinationFolder == null)
                        {
                            rootFolderFolders = rootFolder.Folders;
                            destinationFolder = rootFolderFolders.Add(mIncidentMailFolder);
                        }

                        rule = rules.Create(mRuleName, Outlook.OlRuleType.olRuleReceive);
                        ruleConditions = rule.Conditions;

                        subjectTextRuleCondition = ruleConditions.Subject;
                        subjectTextRuleCondition.Text = new string[] { mSubject };
                        subjectTextRuleCondition.Enabled = true;

                        ruleActions = rule.Actions;
                        moveRuleAction = ruleActions.MoveToFolder;
                        moveRuleAction.Folder = destinationFolder;
                        moveRuleAction.Enabled = true;
                        ruleActions.DesktopAlert.Enabled = true;


                        rules.Save(true);

                        foreach (Outlook.Folder fd in rootFolder.Folders)
                        {
                            if (fd.Name == "Inbox")
                            {
                                rule.Execute(true, fd, true);
                            }
                        }

                    }

                }
                catch (Exception ex)
                {
                    Debug.Write(ex.Message);
                }
                finally
                {
                    if (moveRuleAction != null)
                        Marshal.ReleaseComObject(moveRuleAction);
                    if (ruleActions != null)
                        Marshal.ReleaseComObject(ruleActions);
                    if (subjectTextRuleCondition != null)
                        Marshal.ReleaseComObject(subjectTextRuleCondition);
                    if (ruleConditions != null)
                        Marshal.ReleaseComObject(ruleConditions);
                    if (rule != null)
                        Marshal.ReleaseComObject(rule);
                    if (rootFolderFolders != null)
                        Marshal.ReleaseComObject(rootFolderFolders);
                    if (rootFolder != null)
                        Marshal.ReleaseComObject(rootFolder);
                    if (destinationFolder != null)
                        Marshal.ReleaseComObject(destinationFolder);
                    if (rules != null)
                        Marshal.ReleaseComObject(rules);
                    if (store != null)
                        Marshal.ReleaseComObject(store);
                    if (session != null)
                    {
                        Marshal.ReleaseComObject(session);
                        session = null;
                    }
                    if (OutlookApp != null)
                    {
                        Marshal.ReleaseComObject(OutlookApp);
                        OutlookApp = null;
                    }
                }
            }

    Thereafter I am reading the new mail with particular subject and attachment using below code                                                          

    void Application_New

    MailEx(string EntryIDCollection)
            {
                Outlook.MAPIFolder inBox = (Outlook.MAPIFolder)this.Application.ActiveExplorer().Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);

                //Outlook.MAPIFolder destFolder = null;
                //GetFolderByName(sIncidentMailFolder, ref destFolder);

                Outlook.MailItem newMail = (Outlook.MailItem)Application.Session.GetItemFromID(EntryIDCollection, System.Reflection.Missing.Value);
                if (newMail != null)
                {
                    if (newMail.Subject.ToUpper().Contains(mSubject.ToUpper()))
                    {
                     if (newMail .Attachments.Count > 0)
                                ProcessIncidentMail(newMail);

                    }
                }
            }

    newMail .Attachments.Count throws the exception "The message you specified cannot be found"(newMail.Subject shows correct subject and it's not null) for the first time the new mail is received after rule creation in first step. If the same mail with attachment is send again this exception does not occurs and everything works fine.

    Also note that if I comment out rule creation code part only then , newMail .Attachments.Count is not throwing any exception for the first time when new mail is sent with attachment, but I need to create rule first.

    Please advice.

    Thanks in advance!

    Monday, June 23, 2014 11:21 AM

Answers

  • Hello Anuj,

    You need to review the code, at least you shouldn't release an instance of the Application class:

    if (OutlookApp != null)
    {
         Marshal.ReleaseComObject(OutlookApp);
         OutlookApp = null;
    }

    Use the for loop instead of foreach:

    foreach (Outlook.Folder fd in rootFolder.Folders)

    The foreach loop doesn't allow to release all underlying COM objects.

    Be aware, the Attachments property returns an instance of the Attachments class which should be released after:

    newMail .Attachments.Count 

    You can read more about this in the Systematically Releasing Objects article in MSDN.

    Also I'd recommend breaking the problematic line of code and declare each property or method call separately. Thus, you will find the problematic call exactly. For example:

    this.Application.ActiveExplorer().Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
    

    The ActiveExplorer method of the Application class returns an instance of the Explorer class which should be released after. Then  the Session property returns an instance of the Namespace class which should be released after too. Next, the GetDefaultFolder return an instance of the folder class. Four property and method calls in the single line of code!

    Does the Attachments or Count property fires the exception?

    Monday, June 23, 2014 11:53 AM
  • Thanks Eugene! It was of great help. 

    following line of code was a part of experiment which I forgot to remove

    if (OutlookApp != null)
    {
         Marshal.ReleaseComObject(OutlookApp);
         OutlookApp = null;
    }

    using for loop instead of 

    foreach (Outlook.Folder fd in rootFolder.Folders)

    actually solved my problem.

    Tuesday, June 24, 2014 9:10 AM

All replies

  • Hello Anuj,

    You need to review the code, at least you shouldn't release an instance of the Application class:

    if (OutlookApp != null)
    {
         Marshal.ReleaseComObject(OutlookApp);
         OutlookApp = null;
    }

    Use the for loop instead of foreach:

    foreach (Outlook.Folder fd in rootFolder.Folders)

    The foreach loop doesn't allow to release all underlying COM objects.

    Be aware, the Attachments property returns an instance of the Attachments class which should be released after:

    newMail .Attachments.Count 

    You can read more about this in the Systematically Releasing Objects article in MSDN.

    Also I'd recommend breaking the problematic line of code and declare each property or method call separately. Thus, you will find the problematic call exactly. For example:

    this.Application.ActiveExplorer().Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
    

    The ActiveExplorer method of the Application class returns an instance of the Explorer class which should be released after. Then  the Session property returns an instance of the Namespace class which should be released after too. Next, the GetDefaultFolder return an instance of the folder class. Four property and method calls in the single line of code!

    Does the Attachments or Count property fires the exception?

    Monday, June 23, 2014 11:53 AM
  • Thanks Eugene! It was of great help. 

    following line of code was a part of experiment which I forgot to remove

    if (OutlookApp != null)
    {
         Marshal.ReleaseComObject(OutlookApp);
         OutlookApp = null;
    }

    using for loop instead of 

    foreach (Outlook.Folder fd in rootFolder.Folders)

    actually solved my problem.

    Tuesday, June 24, 2014 9:10 AM