使用Office Interop无法从Outlook删除400多个联系人

时间:2019-05-06 18:07:40

标签: c# outlook 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?

1 个答案:

答案 0 :(得分:3)

在修改集合时请勿使用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%' ")检索他们的条目ID(ExecSQL返回ADODB.Recordset COM对象的实例),使用它来构建一个条目ID数组,并将其传递给RDOFolder.Items.RemoveMultiple()

要创建RDOSession对象的实例,如果不想使用regsvr32.exe在注册表中注册redemption.dll,也可以使用RedemptionLoader类(您可以放置redemption.dll以及可执行文件)。