Надстройка Outlook - не удается перебрать все почтовые элементы в Outlook.Folder с помощью цикла foreach - PullRequest
1 голос
/ 10 марта 2011

Моя надстройка использует Visual Studio 2010 для Outlook 2007. Одной из задач надстройки является перемещение всех почтовых элементов из папки в назначенную папку.

Мой первый этап тестирования просто изменил тему и сохранил письмо в той же папке. Там нет проблем.

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

Мои тестовые данные кажутся мне вполне контролируемыми, так как я перемещаю элементы вручную в папку, которую хочу обработать, прежде чем перейти к коду с помощью отладчика. Например, имея 4 почтовых элемента в папке, я могу переместить 2 из них, и при повторном посещении foreach он выходит из цикла, оставляя 2 почтовых элемента необработанными.

Есть идеи?

        if (ProcessFolder(theRootFolder.FolderPath) && (theRootFolder.Items.Count > 0)) 
        {
            int itemCount = theRootFolder.Items.Count;
            int loopCount = 0;
            MetaDataForm getMetaData = new MetaDataForm(theRootFolder.FolderPath, theRootFolder.Items.Count);
            getMetaData.ShowDialog();
            if (getMetaData.DialogResult == DialogResult.OK)
            {
                string d1 = getMetaData.Meta1;
                string d2 = getMetaData.Meta2;
                try
                {
                    foreach (Object item in theRootFolder.Items)
                    {
                        loopCount++;
                        Outlook.MailItem mi = item as Outlook.MailItem;
                        if (mi != null)
                        {
                            mi.Move(_TRIM_archiveFolder);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ex.ToString();      
                    MessageBox.Show(String.Format("ItemCount={0},LoopCount={1},ExceptionData={2}", 
                                                                itemCount, loopCount, ex));
                }
                MessageBox.Show(String.Format("ItemCount={0},LoopCount={1}",
                                                                itemCount, loopCount));
             }
         }

EDIT:

Отличная идея .... цикл назад решил проблему:

              // iterating backwards is needs because of .move below
                    for (int i = theRootFolder.Items.Count; i > 0; i--)
                    {
                        Outlook.MailItem mi = (Outlook.MailItem)theRootFolder.Items[i];
                        if (mi != null)
                        {
                            if (!mi.Subject.StartsWith("M1"))
                            {
                                mi.Move(_TRIM_archiveFolder);
                            }
                        }
                    }

1 Ответ

3 голосов
/ 10 марта 2011

Обычно при использовании foreach среде выполнения не очень нравится, когда изменяемая коллекция изменяется.

Я делаю здесь дикую догадку, но я думаю, что причина, по которой вы можете переместить 2 из 4 своих элементов, состоит в том, что когда вы переходите к третьей итерации, два оставшихся элемента переместились в Items collection и теперь находятся в позициях 0 и 1, а вы смотрите в позиции 2.

Используйте цикл for или цикл while с Items.Count ()> 0 или что-то в этом роде.

Я также предполагаю, что на самом деле вы получаете исключение, когда это происходит, но оно никогда не всплывает перед вами.Попробуйте прикрепить процесс в WinDbg и посмотрите, что происходит.Вы, вероятно, получаете ошибку COM какой-то.

Разве API-интерфейсы Outlook в значительной степени не все COM-библиотеки?

РЕДАКТИРОВАТЬ:

Ваша идея была правильной.Дали мне идею повторить в обратном направлении:

              // iterating backwards is needed because of .move below
                    for (int i = theRootFolder.Items.Count; i > 0; i--)
                    {
                        Outlook.MailItem mi = (Outlook.MailItem)theRootFolder.Items[i];
                        if (mi != null)
                        {
                            if (!mi.Subject.StartsWith("M1"))
                            {
                                mi.Move(_TRIM_archiveFolder);
                            }
                        }
                    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...