We are writing an MS Outlook plugin. To satisfy our business-logic, it should check all appointments between some dates. We are experiencing several problems with retrieving all items from calendars. We tried two options:
Outlook API. We use the standard logic that is described in MSDN - sort items by [Start], set
IncludeRecurrences
toTrue
and run the Find\Restrict query over calendar items like here. It works fine in our test environment. However, in our customer's environment: For recurring appointments, start and end dates are set to the corresponding dates of a 'master appointment.' For example, in some room's calendar we have a weekly appointment that was created in January, and if we try to find all items in August, we get among others four items of this recurring appointment, but their start and end dates are set to January. But Outlook displays correct dates in the same calendar...Very bad, but we still have WebDAV! We write a simple test application and try to query all items from the calendar using WebDAV. Of course, we didn't reinvent the wheel and just pasted the code from documentation. The previous problem is solved, but the next one arises: It doesn't return recurring items that were created more than approximately six months ago. I Haven't a clue - there are no parameters restricting 'old' items!
What is wrong? Are we missing something important?
Technical details: Exchange 2003, Outlook 2003-2010. Frankly speaking, the first error disappears if we turn on Cached Exchange Mode, but we can't do that.
var nameSpace = application.GetNamespace("MAPI");
var recepient = nameSpace.CreateRecipient(roomEMail);
recepient.Resolve();
var calendar = nameSpace.GetSharedDefaultFolder(recepient, OlDefaultFolders.olFolderCalendar);
var filter = string.Format("[Start]<'{1}' AND [End]>'{0}'",
dateFrom.ToString("dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture), dateTo.ToString("dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture)
);
var allItems = calendar.Items;
allItems.Sort("[Start]");
allItems.IncludeRecurrences = true;
var _item = allItems.Find(filter);
while (_item != null) {
AppointmentItem item = _item as AppointmentItem;
if (item != null) {
if (item.Subject != "some const")
&& (item.ResponseStatus != OlResponseStatus.olResponseDeclined)
&& (item.MeetingStatus != OlMeetingStatus.olMeetingReceivedAndCanceled
&& item.MeetingStatus != OlMeetingStatus.olMeetingCanceled))
{
/* Here we copy item to our internal class.
* We need: Subject, Start, End, Organizer, Recipients, MeetingStatus,
* AllDayEvent, IsRecurring, RecurrentState, ResponseStatus,
* GlobalAppointmentID */
}
}
_item = allItems.FindNext();
}
UPDATE 1:
Additional research using OutlookSpy shows that the problem is not in our code - the Start\End dates are incorrect inside the API when Cached Exchange Mode is off. But Outlook developers were aware of it, and they somehow display correct dates in calendars! Does anyone know how?
UPDATE 2:
Answer from Outlook Support Escalation Engineer:
Based on this, I can confirm that this is a problem in our product.
Restrict
method rather than Find/FindNext? – GraudateFrom.ToString("dd/MM/yyyy HH:mm"
. If your client uses a different date format than you wouldn't that cause the query to fail? – Livestock