Outlook 加载项 - 无法使用 foreach 循环遍历 Outlook.Folder 中的所有邮件项目

发布于 2024-10-21 01:32:46 字数 2464 浏览 2 评论 0原文

我的外接程序使用面向 Outlook 2007 的 Visual Studio 2010。外接程序的一项任务是将所有邮件项目从文件夹移动到指定文件夹。

我的第一阶段测试只是修改了主题并将电子邮件保存在同一文件夹中。那里没有问题。

当我从 .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));
             }
         }

编辑:

好主意......向后循环解决了问题:

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

My add-in is using Visual Studio 2010 targeting Outlook 2007. One task of the add-in is to move all the mailitems from a folder to a designated folder.

My first phase of testing simply modified the subject and saved the email in the same folder. No problems there.

When I changed from the .Save method to use the .Move method, I cannot process all of the items. Some get moved then the foreach loop exits prematurely without throwing any exception.

My test data appears to me to quite controlled in that I move items manually into the folder I want to process before I step thru the code with the debugger. For example, with 4 mailitems in the folder, I can move 2 of them and when the foreach is revisited it goes to exit the loop leaving 2 mailitems unprocessed.

Any ideas?

        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:

Great idea....looping backwards solved the problem:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

荒岛晴空 2024-10-28 01:32:46

一般来说,当使用foreach时,运行时不太喜欢被迭代的集合发生变化。

我在这里进行了大胆的猜测,但我认为您可以从 4 个项目中移动 2 个的原因是,当您进行第三次迭代时,剩下的两个项目已移动到 Items 集合,现在位于位置 0 和 1,而您正在查看位置 2。

使用 for 循环或 while 循环与 Items.Count() > > 0 或类似的东西。

我还猜测,当发生这种情况时,您实际上会遇到异常,但它永远不会突然出现在您面前。尝试在 WinDbg 中附加该进程,看看发生了什么。您可能遇到某种 COM 错误。

Outlook API 不仍然都是 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);
                            }
                        }
                    }

Generally when using foreach, the runtime does not like it too much when the collection being iterated changes.

I'm taking a wild guess here, but I think the reason why you can move 2 out of your 4 items is that when you come to your third iteration the two items that are left has moved in the Items collection and are now on position 0 and 1, while you are looking at position 2.

Use a for loop or a while loop with Items.Count() > 0 or something like that.

I'm also guessing that you in fact are getting an exception when this happens, but it never pops up to you. Try to attach the process in WinDbg and see what's going on. You are probably getting a COM Error of some kind.

Aren't the Outlook APIs pretty much still all COM libraries?

EDIT:

Your idea was right. Gave me the idea to iterate backwards:

              // 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);
                            }
                        }
                    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文