C# Interop.Outlook find messages with specific word in subject

两盒软妹~` 提交于 2019-12-08 09:13:09

问题


I have an application that needs to look for a given word in the subject of emails in the inbox. My code looks like this:

 outlook = new OL.Application();
        outlookNameSpace = outlook.GetNamespace("mapi");

        outlookNameSpace.Logon(Type.Missing, Type.Missing, false, true);

        inbox = outlookNameSpace.GetDefaultFolder(OL.OlDefaultFolders.olFolderInbox);
        inboxItems = inbox.Items;


        string filter = "@SQL =\"http://schemas.microsoft.com/mapi/proptag/0x0037001f\" LIKE 'Michigan'";
        OL.Search advancedSearch = outlook.AdvancedSearch("'inbox'", filter);

When I execute the last statement (advancedSearch = ....), I get the following error message.

An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred

Additional information: The operation failed.

I am new to Advanced Search and DASL queries in general, so my error may be very basic.

I can loop through inboxItems to find the relevant items, but that is rather slow on an a large inbox (6700 items in my case)


回答1:


Try to use PR_NORMALIZED_SUBJECT property (DASL name http://schemas.microsoft.com/mapi/proptag/0x0E1D001F) instead of PR_SUBJECT.

Also, you are not specifying any wildcards for the LIKE operator.




回答2:


If you use a built-in property from the Outlook object model you can use the following namespace:

 urn:schemas:httpmail:subject

So, the filter may look like this:

 string filter = "urn:schemas:mailheader:subject LIKE \'%"+ wordInSubject +"%\'"; 

A sample code is provided below:

using Outlook = Microsoft.Office.Interop.Outlook;
// ...
string advancedSearchTag = "Our first advanced search in Outlook";

private void RunAdvancedSearch(Outlook._Application OutlookApp, 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 = 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 );
  }
  catch(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);
  }                
}

private void adxOutlookEvents_AdvancedSearchComplete(object sender, object hostObj)
{
  Outlook.Search advancedSearch = null;
  Outlook.Results advancedSearchResults = null;
  Outlook.MailItem resultItem = null;
  System.Text.StringBuilder strBuilder = null;
  try
  {
    advancedSearch = hostObj as Outlook.Search;
    if (advancedSearch.Tag == advancedSearchTag)
    {
        advancedSearchResults = advancedSearch.Results;
        if (advancedSearchResults.Count > 0)
        {
            if (HostMajorVersion > 10)
            {
                object folder = advancedSearch.GetType().InvokeMember("Save", 
                                   System.Reflection.BindingFlags.Instance |
                                   System.Reflection.BindingFlags.InvokeMethod | 
                                   System.Reflection.BindingFlags.Public,
                                   null, advancedSearch, 
                                   new object[] { advancedSearchTag });

            }
            else
            {
                strBuilder = new System.Text.StringBuilder();
                strBuilder.AppendLine("Number of items found: " +
                          advancedSearchResults.Count.ToString());                            
                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 Importance: " + 
                                           resultItem.Importance.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 (Exception ex)
    {
       MessageBox.Show(ex.Message, "An exception is occured");
    }
    finally
    {
      if (resultItem != null) Marshal.ReleaseComObject(resultItem);
      if (advancedSearchResults != null) 
                 Marshal.ReleaseComObject(advancedSearchResults); 
    }
  }

You can read more about the AdvancedSearch method of the Application class in the Advanced search in Outlook programmatically: C#, VB.NET article.



来源:https://stackoverflow.com/questions/51048663/c-sharp-interop-outlook-find-messages-with-specific-word-in-subject

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!