Using AdvancedSearch for Outlook with C# Returns Z

2019-09-16 13:02发布

问题:

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;
    }

回答1:

Your filter is working good, use Application:

private Search RunAdvancedSearch(Outlook.Application OutlookApp, string wordInSubject)

https://msdn.microsoft.com/en-us/library/office/microsoft.office.interop.outlook.application.aspx

Read about using _Application and Application in msdn "Remarks". There is very well written.



回答2:

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");
        }
        return advancedSearch;
        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);
        }

    }
    //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?");
    }