我创建了一个简单的 Outlook 插件,用于将联系人从一个文件夹复制到另一个文件夹。(约 5000 个联系人)
为什么我需要这个?有一种奇怪的方法可以创建如上所述的公共地址簿here.
那么为什么不复制公用文件夹中的所有联系人呢?我希望我的团队与我的联系人共享通讯簿,但只有文件名和电子邮件作为信息。
我添加了一个带有两个按钮的工具栏。选择文件夹并同步。
我的问题是,当运行同步一段时间后,我得到
您的服务器管理员限制了您可以同时打开的项目数量。尝试关闭您已打开的邮件或从您正在撰写的未发送邮件中删除附件和图像。
I used Marshal.ReleaseComObject
在每个对象中,尝试在添加之间添加一些延迟。但仍然遇到同样的错误。
然后我在 StackOverflow 找到了一个帖子说要添加GC.Collect
这停止了上面的错误,但 Outlook 总是crashes在同步结束时,有时在中间。
任何帮助将不胜感激。
同步代码
private Task SynchronizeContactsSync()
{
return Task.Run(async () =>
{
if (!synchronizing)
{
synchronizing = true;
Outlook.Folder toFolder = null;
Outlook.Folder fromFolder = null;
try
{
if (!string.IsNullOrWhiteSpace(tEntryID) && !string.IsNullOrWhiteSpace(tStoreID) &&
!string.IsNullOrWhiteSpace(fStoreID) && !string.IsNullOrWhiteSpace(tEntryID))
{
toFolder = Application.Session.GetFolderFromID(tEntryID, tStoreID) as Outlook.Folder;
fromFolder = Application.Session.GetFolderFromID(fEntryID, fStoreID) as Outlook.Folder;
}
if (toFolder != null && fromFolder != null)
{
toFolder.InAppFolderSyncObject = false;
int currentItem = 0;
int itemCount = fromFolder.Items.Count;
//I dont want to use foreach because it keeps reference of each object until is done
//I cast it to list because i cant use for statement with fromFolder.Items
List<Outlook.ContactItem> items = fromFolder.Items.Cast<Outlook.ContactItem>().ToList(); ;
for (int i = 0; i < items.Count; i++)
{
//await Task.Delay(33);
await addContactSync(items[i], toFolder);
if (items[i] != null) Marshal.ReleaseComObject(items[i]);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
currentItem++;
syncText = "Synchronize progress " + currentItem + " of " + itemCount;
}
synchronizing = false;
syncText = "No Synchronize in progress";
}
MessageBox.Show("Done.", "Synchronize", MessageBoxButtons.OK, MessageBoxIcon.Information);
if (toFolder != null) Marshal.ReleaseComObject(toFolder);
if (fromFolder != null) Marshal.ReleaseComObject(fromFolder);
toFolder.InAppFolderSyncObject = true;
}
catch (Exception ex)
{
if (toFolder != null) Marshal.ReleaseComObject(toFolder);
if (fromFolder != null) Marshal.ReleaseComObject(fromFolder);
toFolder.InAppFolderSyncObject = true;
synchronizing = false;
syncText = "No Synchronize in progress";
MessageBox.Show(ex.Message, "Synchronize", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
else
{
MessageBox.Show("Check you settings or please wait for the synchronization to finish.", "Synchronize", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
});
}
private Task addContactSync(Outlook.ContactItem item, Outlook.Folder toFolder)
{
return Task.Run(() =>
{
try
{
if (!string.IsNullOrWhiteSpace(item.Email1Address))
{
string filter = "[FullName] = '" + item.FullName + "'";// "[NickName] = '" + item.NickName + "' or [Email1Address] = '" + item.Email1Address + "' or
Outlook.ContactItem matches = (Outlook.ContactItem)toFolder.Items.Find(filter);
if (matches == null)
{
Outlook.ContactItem contact = toFolder.Items.Add(Outlook.OlItemType.olContactItem);
contact.FullName = item.FullName;
contact.NickName = item.NickName;
contact.Email1Address = item.Email1Address;
contact.Email2Address = item.Email2Address;
contact.Save();
Marshal.ReleaseComObject(contact);
itemSyncCount++;
lastItemSync = DateTime.Now;
}
else
{
matches.Email1Address = item.Email1Address;
matches.Email2Address = item.Email2Address;
matches.Save();
itemSyncCount++;
lastItemSync = DateTime.Now;
}
if (item != null) Marshal.ReleaseComObject(item);
if (matches != null) Marshal.ReleaseComObject(matches);
}
}
catch (Exception ex)
{
Marshal.ReleaseComObject(item);
MessageBox.Show(ex.Message, "Contact", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
});
}