Мы пишем плагин для MS Outlook. Чтобы удовлетворить нашу бизнес-логику, он должен проверять все встречи между некоторыми датами. У нас возникло несколько проблем с получением всех элементов из календарей. Мы попробовали два варианта:
Outlook API. Мы используем стандартную логику, которая описана в MSDN - элементы сортировки по [Start], набор
IncludeRecurrences
дляTrue
и запустить Find \ Ограничить запрос через элементы календаря , как здесь . Он отлично работает в нашей тестовой среде. Однако в среде наших клиентов: для повторяющихся встреч даты начала и окончания устанавливаются на соответствующие даты «основной встречи». Например, в календаре некоторых комнат у нас есть еженедельная встреча, созданная в январе, и если мы попытаемся найти все элементы в августе, мы получим среди прочих четыре элемента этой повторяющейся встречи, но их даты начала и окончания установлены на январь. . Но Outlook отображает правильные даты в том же календаре ...Очень плохо, но у нас все еще есть WebDAV! Мы пишем простое тестовое приложение и пытаемся запросить все элементы из календаря с помощью WebDAV. Конечно, мы не изобретали велосипед, а просто вставили код из документации . Предыдущая проблема решена, но возникает следующая: он не возвращает повторяющиеся элементы, которые были созданы более шести месяцев назад. Понятия не имею - нет параметров, ограничивающих «старые» предметы!
Что случилось? Мы упускаем что-то важное?
Технические детали: Exchange 2003, Outlook 2003-2010. Честно говоря, первая ошибка исчезает, если мы включаем Cached Exchange Mode, но мы не можем этого сделать.
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:
На основании этого я могу подтвердить, что это проблема нашего продукта.