How to detect delete and new AppointmentItem due to updated MeetingRequest email

Add-in Express™ Support Service
That's what is more important than anything else

How to detect delete and new AppointmentItem due to updated MeetingRequest email
 
Joe Acunzo




Posts: 12
Joined: 2012-01-03
Having a problem in my add-in with the way Outlook handles an updated meeting request. As per Microsoft documentation regarding AppointmentItem.Response, when a subsequent meeting request email is responded to for an existing AppointmentItem created from the first meeting request, the original AppointmentItem is deleted, and a new one added. This is most unfortunate, and makes processing difficult.

Here's what they state:

When you call the Respond method with the olMeetingAccepted or olMeetingTentative parameter, Outlook will create a new appointment item that duplicates the original appointment item. The new item will have a different Entry ID. Outlook will then remove the original item.


I need to synchronize an external database with Outlook AppointmentItems. I need to detect this situation of delete and add of a new one so I can update the external database. Right now, I end up with a second record in the database because Outlook is adding a new AppointmentItem.

To handle AppointmentItem deletes, I process BeforeItemMove, and if moving to the DeletedItems folder, I delete the database record. But in this case of an updated meeting request, there is no BeforeItemMove triggered on the folder, just ItemRemove.

Also note I'm trying to avoid connecting to all AppointmentItems. To much overhead regarding performance on startup when somehow has a lot of AppointmentItems. Such as myself, with over 10,000.

On a related topic, how does Outlook correlate the new MeetingRequest to the existing AppointmentItem? If I knew that, it might help me process this situation.
Posted 07 Mar, 2019 16:47:37 Top
Joe Acunzo




Posts: 12
Joined: 2012-01-03
I've made some progress on determing the problem, and it appears to be a bug in Outlook. Could really use some input on this one. Details...

I've discovered the cause of my problem (the duplicate record being written to the external database). When the user responds to the updated meeting request, as stated by Microsoft, Outlook duplicates the AppointmentItem to create a new one and deletes the old one. But it appears Outlook does not properly duplicate the UserProperties property. I use a UserProperty to know where in the external database the appointment lives. Outlook is duplicateing the Name of the UserProperty, but the Value is empty on the new AppointmentItem. Thus my code thinks this is a new appointment, and inserts a new row, instead of updating the existing row. I manually added the Value to my UserProperty on the new AppointmentItem, and everything works as it should with the row in my database being updated instead of a new row added.

Does anyone know if this is a bug in Outlook? I'm using Outlook 2010 (32-bit), and I have all of the latest updates applied. I haven't tried newer version of Outlook yet (need to fire up my VMs).
Posted 08 Mar, 2019 17:22:25 Top
Andrei Smolin


Add-in Express team


Posts: 16223
Joined: 2006-05-11
Hello Joe,

That is, you send a meeting request with a UserProperty on it; the recipient responds with Accepted (for instance) and you get the AppointmentItem without the UserProperty on the recipient's side; is this correct?

I can check this issue in OL2016.

Joe Acunzo writes:
On a related topic, how does Outlook correlate the new MeetingRequest to the existing AppointmentItem? If I knew that, it might help me process this situation.


See https://docs.microsoft.com/en-us/office/vba/api/outlook.meetingitem.getassociatedappointment.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 11 Mar, 2019 02:55:42 Top
Joe Acunzo




Posts: 12
Joined: 2012-01-03
Andrei, no that's not the sequence. This is the sequence of actions:

1) Meeting request received in inbox.

2) User sends response accepting the meeting. Outlook creates a new AppointmentItem on the calendar. My add-in updates the AppointmentItem, adding a UserProperty. (I trap ItemSend and use MeetingItem.GetAssociatedAppointment to get, and update, the AppointmentItem.)

3) Updated meeting requested received with a new time.

4) User sends response accepting the meeting. Outlook duplicates the existing ApointmentItem creating a new one. But the duplicate does not have the UserProperty value set. It actually has the UserProperty Name on the item, but the Value is empty.

Most times, this is the result. I have seen in some test cases, the UserProperty value is being duplicated. I cannot isolate what condition cause it to work versus fail. But 90% of the time, its failing in my Outlook 2010 dev setup.
Posted 11 Mar, 2019 12:52:11 Top
Andrei Smolin


Add-in Express team


Posts: 16223
Joined: 2006-05-11
Hello Joe,

In Outlook 2016, the duplicate in step 4 is a different appointment having no UserProperty.

private void adxOutlookAppEvents1_ItemSend(object sender, ADXOlItemSendEventArgs e)
{
    System.Diagnostics.Debug.WriteLine("!!! adxOutlookAppEvents1_ItemSend. start");
    int stage = 0;
    string myUpName = "myUpName";
    string myUpValue = DateTime.Now.ToShortTimeString();
    if (e.Item is Outlook.MeetingItem)
    {
        Outlook.AppointmentItem appointment = null;
        Outlook.UserProperties userProperties = null;
        Outlook.UserProperty userProperty = null;
        try
        {
            stage = 1;
            Outlook.MeetingItem meeting = e.Item as Outlook.MeetingItem;
            stage = 2;
            appointment = meeting.GetAssociatedAppointment(false);
            stage = 333;
            System.Diagnostics.Debug.WriteLine("!!! adxOutlookAppEvents1_ItemSend. appointment.EntryID=" + appointment.EntryID);
            stage = 3;
            userProperties = appointment.UserProperties;
            stage = 4;
            userProperty = null;
            try
            {
                userProperty = userProperties[myUpName];
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("!!! adxOutlookAppEvents1_ItemSend. Exception: " + ex.Message);
            }
            stage = 5;

            if (userProperty == null)
            {
                userProperty = userProperties.Add(myUpName, Outlook.OlUserPropertyType.olText, false);
                stage = 6;
                userProperty.Value = myUpValue;
                stage = 7;
                System.Diagnostics.Debug.WriteLine("!!! adxOutlookAppEvents1_ItemSend. userProperty == null. New value: " + myUpValue);
            }
            else
            {
                object val = userProperty.Value;
                if (val == null)
                {
                    stage = 8;
                    System.Diagnostics.Debug.WriteLine("!!! adxOutlookAppEvents1_ItemSend. userProperty != null. Existing value: null");
                }
                else
                {
                    stage = 9;
                    System.Diagnostics.Debug.WriteLine("!!! adxOutlookAppEvents1_ItemSend. userProperty != null. Existing value: " + val.ToString());
                }
            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine("!!! adxOutlookAppEvents1_ItemSend. Exception at stage " + stage.ToString() + ": " + ex.Message);
        }
        finally
        {
            if (userProperty != null) Marshal.ReleaseComObject(userProperty); userProperty = null;
            if (userProperties != null) Marshal.ReleaseComObject(userProperties); userProperties = null;
            if (appointment != null) Marshal.ReleaseComObject(appointment); appointment = null;
        }
        DialogResult dialogResult = MessageBox.Show("Send?", "MyAddin52", MessageBoxButtons.YesNo);
        if (dialogResult == DialogResult.No)
        {
            e.Cancel = true;
            System.Diagnostics.Debug.WriteLine("!!! adxOutlookAppEvents1_ItemSend. Do not send");
        }
    }
    System.Diagnostics.Debug.WriteLine("!!! adxOutlookAppEvents1_ItemSend. end");
}


The below is a log created by DebugView (http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx) while sending (1) a confirmation for the original meeting request and doing two attempts (2)(3) to send a confirmation to the updated request. The EntryDs in the ItemSend#1 and ItemSend#2 are different: the first one ends with "10000", the second one ends with "20000". Note that the third ItemSend demonstrates creating a duplicate (EntryID ends with "30000") but the user property is copied and the value is copied as well.


00000213 2:46:53.918 PM [9724] !!! adxOutlookAppEvents1_ItemSend. start
00000214 2:46:53.918 PM [9724] !!! adxOutlookAppEvents1_ItemSend. appointment.EntryID=000000007CB68F605E23924CACFF7E957DE0B80C070041170742DA76834EA4EACCE0A9A68B5B00000000010E000041170742DA76834EA4EACCE0A9A68B5B0004AE3B25910000
00000215 2:46:53.921 PM [9724] !!! adxOutlookAppEvents1_ItemSend. userProperty == null. New value: 2:46 PM
00000216 2:46:58.738 PM [9724] !!! adxOutlookAppEvents1_ItemSend. end
00000228 2:49:23.229 PM [9724] !!! adxOutlookAppEvents1_ItemSend. start
00000229 2:49:23.229 PM [9724] !!! adxOutlookAppEvents1_ItemSend. appointment.EntryID=000000007CB68F605E23924CACFF7E957DE0B80C070041170742DA76834EA4EACCE0A9A68B5B00000000010E000041170742DA76834EA4EACCE0A9A68B5B0004AE3B25920000
00000230 2:49:23.232 PM [9724] !!! adxOutlookAppEvents1_ItemSend. userProperty == null. New value: 2:49 PM
00000231 2:49:41.983 PM [9724] !!! adxOutlookAppEvents1_ItemSend. Do not send
00000232 2:49:41.983 PM [9724] !!! adxOutlookAppEvents1_ItemSend. end
00000243 2:49:47.609 PM [9724] !!! adxOutlookAppEvents1_ItemSend. start
00000244 2:49:47.610 PM [9724] !!! adxOutlookAppEvents1_ItemSend. appointment.EntryID=000000007CB68F605E23924CACFF7E957DE0B80C070041170742DA76834EA4EACCE0A9A68B5B00000000010E000041170742DA76834EA4EACCE0A9A68B5B0004AE3B25930000
00000245 2:49:47.610 PM [9724] !!! adxOutlookAppEvents1_ItemSend. userProperty != null. Existing value: 2:49 PM
00000246 2:49:51.758 PM [9724] !!! adxOutlookAppEvents1_ItemSend. Do not send
00000247 2:49:51.758 PM [9724] !!! adxOutlookAppEvents1_ItemSend. end


Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 13 Mar, 2019 06:58:22 Top