Search code examples
c#outlookinterop

How to delete calendar meeting in outlook non-default calendar


I am trying to delete appointments in outlook, I used code I found here under this subject Get Outlook AppointmentItem using GlobalAppointmentID. In a nutshell, the code adds a custom property to the appointment's UserProperties collection and stores the GlobalAppointmentID as text in the new property, later on search for that property/value combination and do what you need with the appointment. The code works well when the appointment is on the Outlook default calendar, but I cannot find the appoinment when it is on a user created calendar.

I get the error below:

enter image description here

This is the pseudocode to find and delete the appointment:

MAPIFolder calendarFolder = GetCalendar(userCalendar); //find user created calendar

string filter = String.Format("[GAID] = '{0}'", globalAppointmentID); 
Items calendarItems = calendarFolder.Items;
calendarItems.IncludeRecurrences = true;

try
{
    Outlook.AppointmentItem appointmentItem = null;
    appointmentItem = calendarItems.Find(filter);

    if (appointmentItem != null)
    {
        appointmentItem.Delete();
    }
}
catch (System.Exception ex)
{
   throw;
}

I know the property is there because I'm able to loop through the userProperties collection and see its name and value

 foreach (AppointmentItem item in calendarItems)
   {
       for (int i = 1; i <= item.UserProperties.Count; i++)
       {
           Console.WriteLine(item.UserProperties[i].Name);
           Console.WriteLine(item.UserProperties[i].Value);
       }
   }

This seems that it should work to me, but it is not, what am I missing?

Thank you


Solution

  • Outlook would know your property by name (GAID) only if it was added to the folder fields. That would be the case if you called UserProperties.Add with the AddToFolderFields parameter == true.

    If the appointment was moved to a different folder, Outlook would not know what that property name means. You can work around that problem using the DASL property name and the "@SQL=" query prefix instead. To figure out the DASL name of any MAPI property, take a look at it with OutlookSpy (I am its author) - select the appointment with the property in question set, click IMessage button on the OutlookSpy ribbon, select the property, look at the "DASL" edit box. In case of the properties added using UserProperties.Add, the DASL name would be "http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/GAID/0x0000001F"

    string filter = String.Format("@SQL=""http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/GAID/0x0000001F"" = '{0}'", globalAppointmentID); 
    

    Note that the only reason you need to set the custom user property is because Outlook Object Model does not allow to search for the binary (PT_BINARY) MAPI properties, such as GlobalAppointmentID. If using Redemption (I am also its author) is an option, you can use code like the following:

    RDOSession session = new Redemption.RDOSession;
    session.MAPIOBJECT = Application.Session.MAPIOBJECT;
    RDOFolder folder = session.GetFolderFromID(calendarFolder.EntryID);
    string filter = string.Format("GlobalAppointmentID = '{0}'", globalAppointmentID);
    RDOAppointmentItem appointmentItem  = folder.Items.Find(filter);
    if (appointmentItem != null)
    {
       appointmentItem.Delete();
    }