无法使用 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 与您的可执行文件一起)。
我有此代码可以从 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 与您的可执行文件一起)。