Outlook ItemAdd事件为新的日历项目触发两次

时间:2014-06-10 20:54:12

标签: c# calendar outlook outlook-addin

我正在开发一个Outlook加载项,用于监控当前用户的日历,并在收到特定类型的约会或会议时向该用户发送电子邮件。我们有一个第三方应用/服务,它在Outlook中向用户发送新的会议请求,但没有通知登录到Outlook的用户。在我们更换第三方应用程序之前,我的加载项是一种解决方法,因此可以在发送此会议​​请求时向用户发出警报。

我正在使用ItemAdd事件来监控添加约会/会议的时间(即从第三方应用程序发送)。我所看到的是事件触发了两次(即使我只声明了一次处理程序):一次从另一个用户收到约会时,一次时当前用户接受或暂时接受约会。

我需要它才能在首次收到约会时开始,而不是在被接受时开始。我可以监控用户的收件箱,看看他们是否已经收到通知,但我认为如果他们在点击“接受”(服务器延迟?)之前没有真正收到电子邮件,这种方法就不会有效。

这是我的代码。任何想法都将不胜感激。

public partial class ThisAddIn
{
    Outlook.Items _Appointments = null;
    Outlook.Folder _MyAppointmentsFolder = null;

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        // Initialization.
        _MyAppointmentsFolder = (Outlook.Folder)this.Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
        _Appointments = _MyAppointmentsFolder.Items;
        _Appointments.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(appointments_Add);
    }

    private void appointments_Add(object item)
    {
        // An appointment has been added. Read the title and send an email based on a condition.
        Outlook.AppointmentItem meetingItem = item as Outlook.AppointmentItem;
        if (meetingItem.Subject.Contains("Service Call"))
        {
            // Let's send ourselves an email.
            string emailTo = string.Format("{0}@concurrency.com", Environment.UserName);
            string subject = meetingItem.Subject;
            string body = meetingItem.Body;
            string startDate = meetingItem.Start.ToString();
            string endDate = meetingItem.End.ToString();

            SendEmailAlert(emailTo, subject, body, startDate, endDate);
        }

    }
    ....

2 个答案:

答案 0 :(得分:1)

收到会议请求后,Outlook会创建临时暂定约会。接受后,第一个约会被删除,并添加一个新的约会,所以难怪事件发生两次。

如果您转到日历文件夹,单击文件夹按钮,选择项目属性,单击浏览,转到事件选项卡并查看选项卡底部的日志,您是否在OutlookSpy中看到相同的行为? ?

答案 1 :(得分:1)

如果在发送电子邮件后将meetingItem.GlobalAppointmentID的值分配给类级别变量,并在发送之前检查该值,则应防止电子邮件被发送两次。我已经测试了一下这个方法,看起来效果很好。这是我更新的代码:

...

string _PreviousMeetingId = string.Empty; // class-level variable

...

private void appointments_Add(object item)
    {
        // An appointment has been added. Read the title and send an email based on a condition.
        Outlook.AppointmentItem meetingItem = item as Outlook.AppointmentItem;
        if (meetingItem.Subject.Contains("Service Call") && _PreviousMeetingId != meetingItem.GlobalAppointmentID)
        {
            // Let's send ourselves an email.
            string emailTo = string.Format("{0}@concurrency.com", Environment.UserName);
            string subject = meetingItem.Subject;
            string body = meetingItem.Body;
            string startDate = meetingItem.Start.ToString();
            string endDate = meetingItem.End.ToString();

            SendEmailAlert(emailTo, subject, body, startDate, endDate);

            // Save the ID of the meeting so we can check it later (above).
            _PreviousMeetingId = meetingItem.GlobalAppointmentID;
        }

    }