Search code examples
c#searchoutlookadvanced-search

Using AdvancedSearch for Outlook with C# Returns Zero Results


I'm trying to search my inbox and all subfolders for a given string in the subject line. I found the following code online(https://www.add-in-express.com/creating-addins-blog/2012/05/31/outlook-search-csharp-vbnet/), but it returns zero results which is not the expected result.

I looked at the filter under view settings in outlook for a given search term that returns results in the outlook explorer and got this query: "http://schemas.microsoft.com/mapi/proptag/0x0037001f" LIKE '%Ticket%' When I plug that in to the below code I likewise get zero results.

When I use LINQ to query those folders(LINQ is too slow to be a real solution here) I can get results so I'm guessing I'm making a syntactical error with advancedsearch. It is hard to find examples of usage on the web. I will appreciate anyone that can help me.

        private Search RunAdvancedSearch(Outlook._Application OutlookApp, string wordInSubject)
        {
        string advancedSearchTag = "New Search";
        string scope = "Inbox";
        string filter = "\"urn:schemas:mailheader:subject\" LIKE '%"+ wordInSubject +"%'";

        Outlook.Search advancedSearch = null;
        Outlook.MAPIFolder folderInbox = null;
        Outlook.MAPIFolder folderSentMail = null;
        Outlook.NameSpace ns = null;
        try
        {
            ns = OutlookApp.GetNamespace("MAPI");
            folderInbox = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
            folderSentMail = ns.GetDefaultFolder(
                                           Outlook.OlDefaultFolders.olFolderSentMail);
            scope = "\'" + folderInbox.FolderPath +
                                          "\',\'" + folderSentMail.FolderPath + "\'";
            advancedSearch = OutlookApp.AdvancedSearch(
                                            scope, filter, true, advancedSearchTag);
            System.Diagnostics.Debug.WriteLine(advancedSearch.Results.Count);

        }
        catch (System.Exception ex)
        {
            MessageBox.Show(ex.Message, "An exception is thrown!");
        }
        finally
        {
            if (advancedSearch != null) Marshal.ReleaseComObject(advancedSearch);
            if (folderSentMail != null) Marshal.ReleaseComObject(folderSentMail);
            if (folderInbox != null) Marshal.ReleaseComObject(folderInbox);
            if (ns != null) Marshal.ReleaseComObject(ns);
        }


        return advancedSearch;
    }

Solution

  • I was not waiting long enough for the results. When AdvancedSearch(which runs in a separate thread) is finished it fires off an event called AdvancedSearchComplete. I had to tell the code to handle the event in order to wait for the search to complete.

    In RunAdvancedSearch I do this in the Try with this:

    Application.AdvancedSearchComplete += Application_AdvancedSearchComplete;
    

    Here is the whole thing.

        string advancedSearchTag = "MY FOOFOO Search";
        //SEARCH Function
        Search RunAdvancedSearch(Outlook.Application Application, string wordInSubject)
        {
            string scope = "Inbox";
            string filter = "urn:schemas:mailheader:subject LIKE \'%" + wordInSubject + "%\'";
            Outlook.Search advancedSearch = null;
            Outlook.MAPIFolder folderInbox = null;
            Outlook.MAPIFolder folderSentMail = null;
            Outlook.NameSpace ns = null;
            try
            {
                ns = Application.GetNamespace("MAPI");
                folderInbox = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
                folderSentMail = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
                scope = "\'" + folderInbox.FolderPath + "\',\'" +
                                                           folderSentMail.FolderPath + "\'";
                advancedSearch = Application.AdvancedSearch(
                                                    scope, filter, true, advancedSearchTag);
                Application.AdvancedSearchComplete += Application_AdvancedSearchComplete;
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message, "An eexception is thrown");
            }
            finally
            {
                if (advancedSearch != null) Marshal.ReleaseComObject(advancedSearch);
                if (folderSentMail != null) Marshal.ReleaseComObject(folderSentMail);
                if (folderInbox != null) Marshal.ReleaseComObject(folderInbox);
                if (ns != null) Marshal.ReleaseComObject(ns);
            }
            
            return advancedSearch;
        }
        //Handle AdvancedSearchComplete event
        void Application_AdvancedSearchComplete(Outlook.Search SearchObject)
        {
            Outlook.Results advancedSearchResults = null;
            Outlook.MailItem resultItem = null;
            System.Text.StringBuilder strBuilder = null;
            try
            {
                if (SearchObject.Tag == advancedSearchTag)
                {
                    advancedSearchResults = SearchObject.Results;
                    System.Diagnostics.Debug.WriteLine("Count: " + advancedSearchResults.Count);
                    if (advancedSearchResults.Count > 0)
                    {
                        strBuilder = new System.Text.StringBuilder();
                        strBuilder.AppendLine("Number of items found: " +
                                                advancedSearchResults.Count.ToString());
                        foreach (MailItem item in advancedSearchResults)
                        {
                            System.Diagnostics.Debug.WriteLine(item.Subject);
                        }
                        for (int i = 1; i <= advancedSearchResults.Count; i++)
                        {
                            resultItem = advancedSearchResults[i] as Outlook.MailItem;
                            if (resultItem != null)
                            {
                                strBuilder.Append("#" + i.ToString());
                                strBuilder.Append(" Subject: " + resultItem.Subject);
                                strBuilder.Append(" \t To: " + resultItem.To);
                                strBuilder.AppendLine(" \t Date: " +
                                                        resultItem.SentOn.ToString());
                                Marshal.ReleaseComObject(resultItem);
                            }
                        }
                        if (strBuilder.Length > 0)
                            System.Diagnostics.Debug.WriteLine(strBuilder.ToString());
                        else
                            System.Diagnostics.Debug.WriteLine(
                                                        "There are no Mail items found.");
                        
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("There are no items found.");
                    }
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message, "An exception is occured");
            }
            finally
            {
                if (resultItem != null) Marshal.ReleaseComObject(resultItem);
                if (advancedSearchResults != null)
                    Marshal.ReleaseComObject(advancedSearchResults);
            }
        }
      private void btnOutlookSrch_Click(object sender, EventArgs e)
        {
           Outlook.Application OLook = new Outlook.Application();
           RunAdvancedSearch(OLook, "Hello?");
        }