Updating an appointment through CDO & Cached appointment in outlook RRS feed

  • Question

  • Dear Techdudes,


    I'm having troubles with the outlook cached mode in combination with our own exchange (CDO) component.


    First I 've created an appointment through CDO.

    We open the appoinment in outlook and everything is OK. Reminders are working also fine.


    Then when I try to update the same appointment to different start and end times, (See code snippets) the appoinment is moved in the calendar view according to the new times. But.. when I open the appointment it still uses the old times, also I get reminders of this appointment on the old times.


    When we clear the outlook cache (removing offline items on calendar properties) and restart outlook, the appoinment times are correct set to the new updated time.


    We use the 64 bit COM exposed CDO api for communicating with Exchange 2007:


    First the actual managed code snippet used for updating the appointment: (removed error handling)


    Code Snippet


    //parAppointmentId  = permanent url of appointment item


    public void UpdateExchangeAppointment(string parAppointmentId, string parLocation,

    string parSubject, string parBody, DateTime parStartDate, int parDuration,

    string parEnvId, string parAppId, string parSyncId)





    Type t = Type.GetTypeFromProgID("CDO.Appointment");

    appointment = Activator.CreateInstance(t);


    object dataSource = t.InvokeMember("DataSource",System.Reflection.BindingFlags.GetProperty, null, appointment, new object[] { });


    t.InvokeMember("Open", System.Reflection.BindingFlags.InvokeMethod, null, dataSource,

    new object[] { parAppointmentId, Type.Missing, ADODB.ConnectModeEnum.adModeReadWrite });



    ADODB.Fields fields = (ADODB.Fields)t.InvokeMember("Fields", System.Reflection.BindingFlags.GetProperty, null, appointment, null);


    t.InvokeMember("Subject", System.Reflection.BindingFlags.SetProperty, null, appointment,new object[] { parSubject });


    t.InvokeMember("BusyStatus", System.Reflection.BindingFlags.SetProperty, null, appointment,new object[] { "BUSY" });


    t.InvokeMember("Sensitivity", System.Reflection.BindingFlags.SetProperty, null, appointment,new object[] { 0 });


    t.InvokeMember("Location", System.Reflection.BindingFlags.SetProperty, null, appointment,new object[] { parLocation });


    t.InvokeMember("TextBody", System.Reflection.BindingFlags.SetProperty, null, appointment,new object[] { parBody });


    t.InvokeMember("StartTime", System.Reflection.BindingFlags.SetProperty, null, appointment,new object[] { parStartDate });


    t.InvokeMember("EndTime", System.Reflection.BindingFlags.SetProperty, null, appointment, new object[] { parStartDate.AddMinutes((double)parDuration) });


    t.InvokeMember("AllDayEvent", System.Reflection.BindingFlags.SetProperty, null, appointment,new object[] { false });


    ADODB.Field field = (ADODB.Field)t.InvokeMember("Item", System.Reflection.BindingFlags.GetProperty, null, fields,new object[] { _profitAppID });

    field.Value = parAppId;


    field = (ADODB.Field)t.InvokeMember("Item", System.Reflection.BindingFlags.GetProperty, null, fields,

    new object[] { _gcprofitSyncID });

    field.Value = parSyncId;


    field = (ADODB.Field)t.InvokeMember("Item", System.Reflection.BindingFlags.GetProperty, null, fields,

    new object[] { _gcprofitEnvID });

    field.Value = parEnvId;


    field = (ADODB.Field)t.InvokeMember("Item", System.Reflection.BindingFlags.GetProperty, null, fields,

    new object[] { _cdoReminderOffset });

    field.Value = _reminderTimeInSeconds;




    t.InvokeMember("Save", System.Reflection.BindingFlags.InvokeMethod, null, dataSource, new object[] { });




    For easy reading I've included also the 32bit VB code we used in pre-2007 servers:  (removed error handling) We don't know if the problem existed there.


    Code Snippet


    'parAppointmentId  = permanent url of appointment item


    Public Sub UpdateExchangePersonalAppointment(ByVal parAppointmentId As String, _

      ByVal parLocation As String, _

      ByVal parSubject As String, _
      ByVal parBody As String, _

      ByVal parStartDate As Date, _

      ByVal parDuration As Long, _
      ByVal parEnvId As String, _

      ByVal parAppId As String, _

      ByVal parSyncId As String)


    Dim objAppt As CDO.Appointment
    Set objAppt = New CDO.Appointment
    objAppt.DataSource.Open parAppointmentId, , adModeReadWrite
    With objAppt
          .Subject = parSubject
          .Sensitivity = cdoSensitivityNone
          .Location = parLocation
          .TextBody = parBody
          .StartTime = parStartDate
          .EndTime = DateAdd("n", parDuration, parStartDate)
          .AllDayEvent = False

          .Fields(gcProfitAppID).Value = parAppId
          .Fields(gcProfitSyncID).Value = parSyncId
          .Fields(gcProfitEnvID).Value = parEnvId
          .Fields(cdoReminderOffset).Value = gcReminderTimeInSeconds
    End With




    Thursday, November 20, 2008 9:01 AM