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

本文关键字:两次 事件 ItemAdd 日历 Outlook | 更新日期: 2023-09-27 18:07:56

我正在开发一个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);
        }
    }
    ....

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

如果您在发送电子邮件后将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;
        }
    }

当收到会议请求时,Outlook会创建一个临时的暂定约会。在您接受它之后,第一个约会被删除,一个新的约会被添加,所以事件触发两次也就不足为奇了。

你应该在OutlookSpy(我是它的作者)中看到同样的行为,如果你去日历文件夹,点击文件夹按钮,选择项目属性,点击浏览,转到事件选项卡,查看标签底部的日志,同时接收和接受会议

当收到会议请求时,Outlook会创建一个临时的暂定约会。在您接受它之后,第一个约会被删除,一个新的约会被添加,所以事件触发两次也就不足为奇了。

你在OutlookSpy(我是它的作者)中看到同样的行为吗?如果你去日历文件夹,点击文件夹按钮,选择项目属性,点击浏览,转到事件选项卡并查看选项卡底部的日志?