C#Outlook VSTO联系人在删除时重复复制

时间:2016-02-15 10:12:20

标签: c# outlook vsto contacts outlook-addin

更新联系人时,我只是删除旧联系人并将其替换为新联系人,因为我无法检查所有联系人的所有字段。

private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        string sTempPath = GetTemporaryDirectory();

        //RequestContacts();
        ExtractContacts(sTempPath);
        ImportContacts(sTempPath);
    }

" RequestContacts()"将联系人从服务器以zip格式下载到apps目录。

public string GetTemporaryDirectory()
    {
        string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
        Directory.CreateDirectory(tempDirectory);
        return tempDirectory;
    }

这只是找到一个临时文件夹来提取联系人然后从Outlook导入。

private void ExtractContacts(string sExtractPath)
    {
        string sImportPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
        string sZipPath = sImportPath.Substring(6, sImportPath.Length - 6) + "/contacts.zip";
        ZipFile.ExtractToDirectory(sZipPath, sExtractPath);
    }

这会将下载的联系人从zip中提取到临时文件夹。

private void ImportContacts(string sImportPath)
    {
        var oldContacts = Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts).Items.Cast<Outlook.ContactItem>()
            .Where(c => c.ManagerName.Equals("QERP"));
        foreach (var oldContact in oldContacts)
        {
            oldContact.Delete();
        }

        var newContacts = Directory.GetFiles(sImportPath, "*.vcf").Select(Application.Session.OpenSharedItem).Cast<Outlook.ContactItem>();
        foreach (var newContact in newContacts)
        {
            newContact.ManagerName = "QERP";
            newContact.Save();
        }
    }

这会删除我们下载的旧联系人,而不是我们未通过此应用下载的联系人。

问题在于它不会删除所有联系人。由于某种原因,它总是删除半+ 1。

3 个答案:

答案 0 :(得分:0)

我建议从发布底层COM对象开始,避免在单行代码中出现多个点。例如:

 Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts).Items

Application类的Session属性返回Namespace类的一个实例,该实例应该在之后发布。 Namespace类的GetDefaultFolder方法返回应该释放的MAPIFolder类的实例。

完成使用后,使用System.Runtime.InteropServices.Marshal.ReleaseComObject释放Outlook对象。如果您的加载项尝试枚举存储在Microsoft Exchange Server上的集合中超过256个Outlook项目,这一点尤为重要。如果您未及时发布这些对象,则可以达到Exchange对任何时候打开的最大项目数的限制。然后在Visual Basic中将变量设置为Nothing(C#中为null)以释放对该对象的引用。请在Systematically Releasing Objects文章中详细了解相关内容。

    foreach (var oldContact in oldContacts)
    {
        oldContact.Delete();
    }

改为使用for循环。它将允许立即释放代码中的底层COM对象。为了删除Outlook项目,我建议使用while循环,您可以在其中查看可用项目数或for循环减少计数器。

答案 1 :(得分:0)

删除项目时不要使用“foreach”循环 - 您正在修改集合,因此跳过了一半的项目。使用向下“for”循环

Outlook.Items items = oldContacts.Items;
for (int i = items.Count; i >= 1; i--)
{
   Outlook.ContactItem contact = items[i] as Outlook.ContactItem; 
   if (contact != null)  //could be a distribution list
   {
      contact.Delete();
   } 
}

答案 2 :(得分:0)

正在运行并删除所有联系人。我弄清楚了什么。 帮我清理编码。

    private void Contact_Sil()
    {
        var Eski_Contacts = Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts).Items.Cast<Outlook.ContactItem>();
        while ( Eski_Contacts.Count()>0)
        {
            Eski_Contacts = Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts).Items.Cast<Outlook.ContactItem>();
            foreach (var oldContact in Eski_Contacts)
            {
                oldContact.Delete();
            }                
        }
    }