C# Outlook 2007 надстройка: рекурсивный анализ почтовых элементов

Я пишу надстройку для Outlook, чтобы анализировать все письма в папке, нажав на кнопку пользовательского контекстного меню. Я подключил кнопку, но при попытке использовать цикл foreach внутри папки для проверки почтовых элементов, кажется, что проверяется только первый.

Я беру детали папки здесь:

void Application_FolderContextMenuDisplay(Office.CommandBar CommandBar, ***MAPIFolder Folder***)

Затем я передаю его парсеру:

public void checkFolder(MAPIFolder folder)
    {
        MailParser parser = new MailParser();
        foreach (MailItem item in folder.Items)
        {
            parser.parseMail(item);
        }
    }

Это foreach здесь, который, кажется, терпит неудачу.

Есть идеи? Это сводит меня с ума.

4 ответа

Решение

Я не очень хорошо знаком с объектной моделью outlook, но сразу скажу, что проблема в том, что вы ошибочно полагаете, что все элементы в папке MailItem экземпляров. Они также могут быть такими объектами, как ContactItem, Вам необходимо явно проверить, является ли значение MailItem вот так

foreach ( object current in folder.Items ) {
  MailItem mi = current as MailItem;
  if ( mi != null ) { 
    parser.parseMail(mi);
  }
}

Вы должны использовать Microsoft.Office.Interop.Outlook.Extensions.Linq API, который позволяет безопасный тип поиска элементов:

public void checkFolder(MAPIFolder folder)
{
    MailParser parser = new MailParser();
    IQueryable<Mail> query = folder.Items.AsQueryable<Mail>();
    foreach (MailItem wrappedItem in query)
    {
        parser.parseMail(wrappedItem.Item);
    }
}

Здесь Mail тип является подклассом OutlookItemBase<TaskItem>, Имеет Item свойство, которое возвращает MailItem COM-объект. Он также будет безопасно отфильтровывать несовместимые типы без исключения, поэтому вам не нужно добавлять нулевые проверки.

API расширений также решает проблему отсутствующего базового класса для элементов, так что вы, наконец, можете получить доступ к UserProperties и такой через неуниверсальный OutlookItem Базовый класс. Также API поддерживает некоторые атрибуты, которые могут повысить производительность запросов Linq, выполняя их на стороне Outlook, а не на COM. К сожалению, они плохо документированы.

Я предполагаю, что MAPIFolder.Items не является строго типизированным, но вы перебираете его так, как будто это так. Я бы предложил пойти с:

foreach(object item in folder.Items)
{
  if (item is MailItem)
    parser.parseMail((MailItem)item);
}

foreach полезно для коллекции, которая реализует IEnumerable интерфейс. Согласно MSDN, это будет Items Коллекция не реализует IEnumerable, Попробуйте использовать for цикл вместо:

int c = folder.Items.Count
for (i=0;i<=c;i++)
{
   //Do your thing
}
Другие вопросы по тегам