C#Outlook关联收件箱和已发送的项目

时间:2013-04-02 11:42:49

标签: c# outlook-2007

我正在开发一个软件,我可以检索收件箱并从Outlook发送项目。我想要做的是将收件箱电子邮件与回复联系起来(如果有人发送了对该电子邮件的回复)。列表应按此顺序显示

Sender@abc.com收到的主题收到的时间 sender@abc.com回复主题发送时间

我打算做的是检索一个数据表中的收件箱项目和另一个数据表中的已发送项目。它根据发件人电子邮件和主题逐个读取电子邮件,然后在发送的项目中搜索发件人和电子邮件,如果匹配,则将其合并到第三个数据表。

还有其他更好的方法吗?

以下是代码:

 private DataTable GetInboxItems()

    {
        DataTable inboxTable;
        //try
        //{
        filter = "[ReceivedTime] >= '" + dtpStartDate.Value.ToString("dd/MM/yyyy 12:00 AM") + "' and [ReceivedTime] <= '" + dtpEndDate.Value.ToString("dd/MM/yyyy  11:59 PM") + "'";
        Outlook.Application outlookApp = GetApplicationObject();
        Outlook.Folder root = outlookApp.Session.DefaultStore.GetRootFolder() as Outlook.Folder;
        EnumerateFolders(root);
        //string filter = "[ReceivedTime] > '" + dtpStartDate.Value.ToString("dd/MM/yyyy") + "'";

        //inbox
        Outlook.MAPIFolder inboxFolder = outlookApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
        inboxTable = CreateTable();
        int count = 0;


        if (inboxFolder.Items.Count > 0)
        {

            var restrictedItems = inboxFolder.Items.Restrict(filter);
            restrictedItems.Sort("[ReceivedTime]", true); //descending
            //foreach (var item in inboxFolder.Items)
            foreach (var item in restrictedItems)
            {
                var mail = item as Outlook.MailItem;
                if (mail != null)
                {
                    //try
                    //{
                    DataRow row = inboxTable.NewRow();
                    //row["sn"] = (++count).ToString();
                    row["sn"] = mail.EntryID + " " + mail.ReceivedByEntryID;
                    row["MailType"] = "Inbox";
                    row["SenderName"] = mail.SenderName;
                    row["SenderEmail"] = mail.SenderEmailAddress;
                    row["ReceivedDate"] = mail.ReceivedTime;
                    row["Subject"] = mail.Subject;
                    row["Body"] = mail.Body != null ? (mail.Body.Length > 25 ? mail.Body.Substring(0, 25) : mail.Body) : null;
                    //row["Body"] = mail.Body != null ? mail.Body : "";
                    row["MailSize"] = mail.Size.ToString();
                    string attachments = null;
                    if (mail.Attachments.Count > 0)
                    {
                        foreach (var attachment in mail.Attachments)
                        {
                            if (((Outlook.Attachment)attachment) != null)
                                //attachments = ((Outlook.Attachment)attachment).FileName + " " + ((Outlook.Attachment)attachment).Size.ToString() + ", ";
                                attachments += (((Outlook.Attachment)attachment).Size / 1024).ToString() + " KB, ";
                        }
                    }


                    row["AttachmentCount"] = mail.Attachments.Count;
                    if (attachments != null)
                        row["AttachmentSize"] = attachments.Substring(0, attachments.Length - 2);

                    inboxTable.Rows.Add(row);
                }
                //catch (Exception ex)
                //{

                //    return null;
                //}

            }
        }

        return inboxTable;
    }

1 个答案:

答案 0 :(得分:0)

我在outlook插件中制作了这种东西

没有百分之百的方法来制作它...... 问题是对话ID并不总是由其他软件保存。因此,您需要使用一组数据将电子邮件链接到他们的答案:
  - 消息ID:这在电子邮件标题中可用。已发送的项目没有:/
  - In-Reply-To:这也在电子邮件标题中   - 主题ID

对于主题ID,我按此顺序检索值(我取第一个可用的值):
  - MailItem.ConversationIndex:每个回复都将字节添加到会话索引
  - 参考标题

然后,我使用topicID将电子邮件链接到他们的回复,电子邮件具有与回复相同的前X个字符。示例原始电子邮件主题id = abc,reply = abcdef 对于使用会话ID无法链接的所有邮件,我尝试使用Message-ID&amp; In-Reply-To ID

问题尤其来自outlook发送的电子邮件(没有Message-ID),然后没有Reference / ConversationIndex标题的用户回复......你将无法将两个邮件链接在一起。

希望有所帮助

编辑:这是一些代码。我从不同的类/方法复制/粘贴代码以创建单个方法,因此可能无法编译。把它当作伪代码。

public SimpleTree<MailData> CreateTree(List<MailData> mails)
{
    mails.Sort((m1, m2) => m1.TopicId == m2.TopicId ? m2.CreationDate.CompareTo(m1.CreationDate) : m1.TopicId.CompareTo(m2.TopicId));

    var tree = new SimpleTree<MailData>();

    var i = 0;
    while (i < mails.Count)
    {
        var node = tree.Children.Add(mails[i]);
        var topicId = mails[i].TopicId;
        var start = i + 1;
        while (start < mails.Count 
            && !string.IsNullOrEmpty(topicId) 
            && !string.IsNullOrEmpty(mails[start].TopicId) 
            && mails[start].TopicId.StartsWith(topicId))
        {
            node.Children.Add(mails[start]);
            start++;
        }
        i = start;
    }

    // Handle email where TopicId are different, but ParentId is filled with correct value
    for (int j = tree.Children.Count - 1; j >= 0; j--)
    {
        var child = tree.Children[j];
        if (child.Children.Count == 0 && !string.IsNullOrEmpty(child.Value.ParentId))
        {
            var parentNode = tree.FindNode(s => s != null && s.MessageId == child.Value.ParentId);
            if (parentNode != null && parentNode != child)
                parentNode.Children.Add(child);
        }
    }

    return tree;
}

MailData是一个类,需要3个字段,如前所述:

  • MessageID(来自Message-ID标头)
  • ParentId(来自In-Reply-To标题)
  • TopicId(来自ConversationIndex或参考标题)

SimpleTree&LT;&GT;是一个创建树的类,它实际上是一个带有子节点的节点。没有什么特别的或与电子邮件有关。 .Value属性引用与节点关联的数据(此处为MailData)

目标是对TopicId进行排序,以便我们可以在1循环中构造树 然后我检查树根中的所有邮件,检查我们是否可以在另一封邮件下移动它们使用MessageId / ParentId

请记住,它会创建一个单层树,例如:

  • 邮件A.
    • 回复AA
    • 回复AAA
  • 邮件B
    • 回复BB
    • 回复BBB

但你需要这样的东西:

  • 邮件A.
    • 回复AA
      • 回复AAA
  • 邮件B
    • 回复BB
      • 回复BBB