无法使用 Office Interop 从 Outlook 中删除超过 400 个联系人

Unable to delete over 400 contacts from Outlook using Office Interop

我有此代码可以从 Microsoft Outlook 中删除具有特定用户的所有联系人 属性:

public void PurgePTSContacts(ref long rlCount)
{
    int iLastPercent = 0;
    rlCount = 0;

    try
    {

        // Get the MAPI namespace object (not sure exactly what this is)
        Outlook.NameSpace MAPI = _OutlookApp.GetNamespace("MAPI");
        if (MAPI != null)
        {
            // Now get the default Outlook Contacts folder
            Outlook.MAPIFolder oFolder = MAPI.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
            if (oFolder != null)
            {
                // Ensure it is a calendar folder.  This test is not strictly required.
                if (oFolder.DefaultItemType == Outlook.OlItemType.olContactItem)
                {
                    // Get the collect of items from the calendar folder
                    Outlook.Items oFolderItems = oFolder.Items;
                    if (oFolderItems != null)
                    {
                        int iNumItems = oFolderItems.Count;

                        // Progress to do

                        int iItem = 0;
                        foreach (object oItem in oFolderItems)
                        {
                            iItem++;

                            if(oItem is Outlook.ContactItem )
                            {
                                Outlook.ContactItem oContact = (oItem as Outlook.ContactItem);

                                int iPercent = ((iNumItems - iItem) + 1) * 100 / iNumItems;
                                if (iPercent >= iLastPercent + 5 || iPercent == 100)
                                {
                                    iLastPercent = iPercent;
                                    // Show progress
                                }

                                Outlook.UserProperties oContactDetails = oContact.UserProperties;
                                if (oContactDetails != null)
                                {
                                    if (oContactDetails.Find("xxxxx") != null)
                                    {
                                        oContact.Delete();
                                        rlCount++;
                                    }
                                }

                                oContact = null;
                            }
                        }
                    }
                }
            }
        }
    }
    catch (Exception e)
    {
        MessageBox.Show(e.ToString());
    }
}

现在不明白的是导入联系人的时候有428个,删除联系人的时候只有200多个,然后我就得反复调用我的PurgePTSContacts 方法,它会清除更多。

随着每个后续调用越来越少被清除,直到它为 0。

为什么我不能在一个函数调用中清除所有 400x?

修改集合时不要使用 foreach - 使用向下循环:

for (int i = FolderItems.Count; i >= 1; i--)
{
  object oItem = FolderItems[i];
  Outlook.ContactItem oContact = (oItem as Outlook.ContactItem);
  if (oContact  != null)
  {
    ...
    Marshal.ReleaseComObject(oContact);
  }
  Marshal.ReleaseComObject(oItem);
}
                    

更新。根据 OP 请求,一个示例显示如何使用 Redemption(我是其作者)删除文件夹中的所有项目:

RDOSession session = new RDOSession();
session.MAPIOBJECT = MAPI.MAPIOBJECT; //an instance of the Namespace object from your snippet above
RDOFolder rFolder = session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts); //or you can use RDOSession.GetFolderFromID if you already have an Outlook.MAPIFolder
rFoldder.EmptyFolder ();

如果您只想删除联系人(而不是通讯组列表),您可以先使用 RDOFolder.Items.MAPITable.ExecSQL("SELECT EntryID from Folder where MessageClass LIKE 'IPM.Contact%' ")(ExecSQL returns ADODB.Recordset COM 对象的一个​​实例来检索他们的条目 ID ), 用它来构建条目 ID 数组,并将其传递给 RDOFolder.Items.RemoveMultiple().

如果您不想使用 regsvr32.exe 在注册表中注册 redemption.dll,则创建 RDOSession object, you can also use the RedemptionLoader class 的实例(您可以将 redemption.dll 与您的可执行文件一起)。