Мы пишем плагин для MS Outlook. Чтобы удовлетворить нашу бизнес-логику, он должен проверять все встречи между датами. У нас возникли некоторые проблемы с извлечением всех элементов из календарей. Мы попробовали два варианта:
Outlook API. Мы используем стандартную логику, описанную в MSDN, - сортируем элементы по [Start], устанавливаем
IncludeRecurrences
вTrue
и запускаем запрос Find\Restrict по элементам календаря , как здесь. Он отлично работает в нашей тестовой среде. Тем не менее, в среде наших клиентов: для повторяющихся встреч даты начала и окончания устанавливаются на соответствующие даты "основной встречи". Например, в каком-то календаре помещений у нас есть еженедельная встреча, которая была создана в январе, и если мы попытаемся найти все элементы в августе, мы получим среди прочих четыре элемента этой повторяющейся встречи, но их даты начала и окончания установлены на январь, Но Outlook отображает правильные даты в том же календаре...Очень плохо, но у нас все еще есть WebDAV! Мы пишем простое тестовое приложение и пытаемся запросить все элементы из календаря, используя WebDAV. Конечно, мы не изобретали велосипед и просто вставили код из документации. Предыдущая проблема решена, но возникает следующая: она не возвращает повторяющиеся элементы, созданные более шести месяцев назад. Понятия не имею - нет параметров, ограничивающих "старые" предметы!
Что случилось? Мы что-то упустили?
Технические подробности: Exchange 2003, Outlook 2003-2010. Честно говоря, первая ошибка исчезает, если мы включаем режим кэширования Exchange, но мы не можем этого сделать.
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();
}
ОБНОВЛЕНИЕ 1:
Дополнительное исследование с использованием OutlookSpy показывает, что проблема не в нашем коде - даты начала\окончания неверны внутри API, когда режим кэширования Exchange отключен. Но разработчики Outlook знали об этом, и они каким-то образом отображают правильные даты в календарях! Кто-нибудь знает как?
ОБНОВЛЕНИЕ 2:
Ответ инженера по поддержке поддержки Outlook:
Исходя из этого, я могу подтвердить, что это проблема в нашем продукте.