В последние годы электронная почта является
неотъемлемой составляющей персональных информационных средств. С большой
степенью вероятности верно то, что, если у человека на столе стоит компьютер, то
на нем установлена та или иная система электронной почты. Вместе с тем типичные
приложения для работы с электронной почтой в чистом виде далеко не всегда
отвечают требованиям автоматизации трудовой деятельности пользователя. В связи с
этим существует потребность в создании различного рода приложений, не являющихся
частью почтовых систем, но вместе с тем предоставляющих пользователю некоторые
средства для работы с электронной почтой. Программный интерфейс MAPI, о котором
пойдет речь в этой статье, является одним из средств, позволяющим создавать
подобные приложения на платформе Windows.
В широком понимании MAPI (Messaging Application
Programming Interface) - это целая архитектура, специфицирующая процессы
взаимодействия отдельных приложений с различными почтовыми системами.
Архитектура MAPI описывает так называемую подсистему MAPI, которая обеспечивает
взаимодействие клиентских приложений с различными службами почтовой системы,
такими как служба хранения информации, служба адресной книги, служба транспорта
и т.д. С другой стороны MAPI - это прикладной интерфейс, который был создан для
того, чтобы разработчики на С, С++, Visual Basic (а в последствии и Visual Basic
Script) имели возможность добавлять в свои приложения функциональность для
работы с электронной почтой. С точки зрения прикладной программы подсистема MAPI
- это набор динамических библиотек, содержащих функции и
объектно-ориентированные интерфейсы, благодаря которым взаимодействуют
клиентские и серверные части почтовых приложений. О MAPI можно говорить много и
долго (благо компания Microsoft постаралась сделать из MAPI очередного
программного 'монстра'), но наибольший интерес для разработчиков представляют
так называемые клиентские прикладные программные интерфейсы, среди которых
следует выделить в первую очередь Simple MAPI, MAPI и CDO.
Simple MAPI предоставляет в распоряжение
разработчиков всего 12 простейших функций. Они позволяют выполнять такие
действия, как 'сформировать сообщение', 'указать адрес получателя', 'отправить',
'получить'. Причем все операции с сообщениями можно производить только в рамках
одной папки, являющейся папкой для входящих сообщений текущего контейнера
доставки (в почтовой системе MS Exchange Server это обычно 'Inbox' или
'Входящие' в русскоязычной версии). Разработчик не имеет доступа к полной
структуре папок почтового сервера, то есть может контролировать сообщение лишь
до тех пор, пока пользователь не переместит его из папки 'Inbox' в какую-либо
другую.
Другим недостатком Simple MAPI является то, что
он позволяет работать только со стандартными полями сообщения, такими как
'Тема', 'Отправитель', 'Получатель', 'Дата отправки', 'Текст сообщения', 'Класс
сообщения', а также с вложенными файлами. При всей своей ограниченности Simple
MAPI подкупает имено простотой в освоении и использовании. Тому, кто имеет даже
небольшой опыт программирования на С или Visual Basic достаточно нескольких
минут для, того чтобы научиться использовать этот интерфейс.
Следующий фрагмент кода на языке С позволит
убедиться в этом (для простоты несущественные участки кода, такие как объявление
переменных и обработка ошибок опущены). MAPILogon(0,"My Profile", NULL, MAPI_NEW_SESSION, 0, &pSession);
MAPIResolveName(pSession, 0, "Bill Gates", 0, 0, &pRecipient);
ZeroMemory(&pMessage, sizeof(pMessage))
pMessage.lpszSubject = " Greeting";
pMessage.lpszNoteText = "Hello Bill!";
pMessage.nRecipCount = 1;
pMessage.lpRecips = Recipient;
MAPISendMail(pSession, 0, &pMessage, 0, 0);
MAPILogoff(pSession, 0, 0, 0);
В приведенном примере формируется сообщение с
темой 'Greeting', содержащее текст 'Hello Bill!' и отправляется адресату,
видимое имя которого в адресной книге 'Bill Gates'. Сейчас мы разберем по шагам
как это делается.
Первым делом клиентской программе необходимо
начать сеанс работы с почтовой системой, для чего при помощи функции MAPILogon
открывается сессия Simple MAPI. Затем из видимого имени ('Bill Gates') функция
MAPIResolveName формирует структуру, содержащую точную и полную информацию об
адресате (в частности его электронный адрес). Полученная информация об адресате
наряду с темой и текстом формирует структуру, содержащую почтовое сообщение,
готовое к отправке. Функция MAPISendMail отправляет сообщение по электронной
почте. Наконец, функция MAPILogoff завершает сеанс работы с почтовой системой,
закрывая сессию Simple MAPI.
Просто, не правда ли? Немного модифицировав
программу, можно дать ей возможность отправлять сообщения, содержащие не только
текст, но и вложенные файлы. Изучив еще пару-тройку функций Simple MAPI, можно с
легкостью запрограммировать получение анализ и удаление сообщений, содержащихся
в почтовом ящике пользователя.
Simple MAPI позволяет запрограммировать две
основные функции электронной почты - отправку и прием сообщений. Зачастую это
вся функциональность, необходимая приложению для работы с электронной почтой.
Типичными примерами использования Simple MAPI являются приложения, производящие
рассылку сообщений (возможно однотипных, по шаблону) множеству адресатов, а
также приложения, время от времени сканирующие почтовый ящик пользователя и
производящие анализ и обработку поступающей в него корреспонденции.
Программисты на С найдут определения всех
функций, структур и констант Simple MAPI в файле MAPI.H, входящем в состав
Microsoft Visual Studio. Его аналогом для Visual Basic является файл MAPI.BAS.
Сами функции находятся в динамической библиотеке MAPI.DLL. Как правило Simple
MAPI входит в состав клиентских почтовых программ, причем не только работающих в
архитектуре "клиент-сервер" (MS Outlook, MS Exchange Client), но и
обычных (MS Outlook Express, Eudora Pro, а в скором будущем и The Bat!).
Simple MAPI на то и 'Simple', что накладывает
серьезные ограничения на разработчика как в плане функциональности, так и в
плане производительности приложения. Полностью снять эти оковы позволяет гибкий
и мощный программный интерфейс MAPI 1.0 (в прошлом - Extended MAPI по аналогии с
Simple MAPI). MAPI 1.0 - это совокупность более ста функций и нескольких
десятков COM-интерфейсов, предоставляющих программистам на С и С++ богатый
инструментарий для создания приложений, работающих с электронной почтой. Simple
MAPI можно назвать оберткой MAPI 1.0, которая скрывает множество деталей и
нюансов взаимодействия приложений с почтовыми системами.
MAPI 1.0 предоставляет разработчику не только
возможность реализации таких простых функций как отправка или прием почтовых
сообщений, но и механизмы для более тесного взаимодействия с отдельными частями
систем электронной почты - с адресной книгой, иерархической структурой папок на
почтовом сервере, службой транспорта и т.д. Более того, с помощью MAPI 1.0 можно
создавать даже части почтовых систем - программные шлюзы, различные службы
обработки информации, которые являются частью MAPI-совместимых почтовых
серверов. Не будет преувеличением сказать, что, используя MAPI 1.0 можно создать
свою собственную клиентскую почтовую программу, аналогичную MS Oulook со всеми
ее богатыми возможностями.
Вместе с тем создание приложений на базе MAPI
1.0 - более трудоемкий процесс, нежели программирование с использованием Simple
MAPI. MAPI 1.0 требует от разработчика дополнительной квалификации, в частности
знания технологии COM. Перепишем уже имеющийся пример с использованием MAPI 1.0.
Для наглядности каждый блок кода сопоставлен с соответствующим фрагментом из
предыдущего примера. // Begin MAPILogon(:);
MAPILogonEx(0, "My Profile", NULL, MAPI_NEW_SESSION, &lpSession);
// End MAPILogon(:);
lpSession->GetMsgStoresTable(0, &StoresTable);
HrQueryAllRows(StoresTable, (LPSPropTagArray)&tagDefaultStore,
NULL, NULL, 0, &lpRow);
for(i = 0; i < lpRow -> cRows; i++)
{
if(lpRow->aRow[i].lpProps[0].Value.b == TRUE)
break;
}
lpSession->OpenMsgStore(0,
lpRow->aRow[i].lpProps[1].Value.bin.cb,
(LPENTRYID)lpRow->aRow[i].lpProps[1].Value.bin.lpb,
NULL, MDB_WRITE, &lpMDB);
lpMDB->OpenEntry(lpPropValue -> Value.bin.cb,
(LPENTRYID)lpPropValue -> Value.bin.lpb,
NULL, MAPI_MODIFY, &ulObjType,
(LPUNKNOWN *)&lpFolder);
lpFolder->CreateMessage(NULL, 0, &lpMsg);
SInitPropValue MsgProps[] =
{
{PR_DELETE_AFTER_SUBMIT, 0, TRUE},
{PR_MESSAGE_CLASS, 0, (ULONG)"IPM.NOTE "},
{PR_SUBJECT, 0, (ULONG)"Greeting"},
{PR_BODY, 0, (ULONG)" Hello Bill!"}
};
lpMsg->SetProps(4, (LPSPropValue)&MsgProps, NULL);
// Begin MAPIResolveName(:);
lpSession->OpenAddressBook(0, NULL,
AB_NO_DIALOG, &lpAdrBook);
MAPIAllocateBuffer(CbNewADRLIST(1), (LPVOID*)&lpAdrList);
MAPIAllocateBuffer(2*sizeof(SPropValue),
(LPVOID*)&(lpAdrList -> aEntries -> rgPropVals));
ZeroMemory(lpAdrList -> aEntries -> rgPropVals,
2*sizeof(SPropValue));
lpAdrList->cEntries = 1;
lpAdrList->aEntries[0].ulReserved1 = 0;
lpAdrList->aEntries[0].cValues = 2;
lpAdrList->aEntries[0].rgPropVals[0].ulPropTag = PR_DISPLAY_NAME;
lpAdrList->aEntries[0].rgPropVals[0].Value.lpszA = "Bill Gates";
lpAdrList->aEntries[0].rgPropVals[1].ulPropTag = PR_RECIPIENT_TYPE;
lpAdrList->aEntries[0].rgPropVals[1].Value.l = MAPI_TO;
lpAdrBook->ResolveName(0, 0, NULL, lpAdrList);
lpMsg->ModifyRecipients(MODRECIP_ADD, lpAdrList);
// End MAPIResolveName(:);
// Begin MAPISendMail(:);
lpMsg->SubmitMessage(0);
// End MAPISendMail(:);
// Begin MAPILogoff (:);
lpSession->Logoff(0, 0, 0);
// End MAPILogoff (:);
Как видно из этого примера большинство операций,
являющихся примитивными для Simple MAPI, в MAPI 1.0 состоят из
последовательностей вызовов тех или иных методов различных интерфейсов. Так, для
того, чтобы создать сообщение в MAPI 1.0 требуется получить доступ и открыть
контейнер с сообщениями, отыскать в нем папку для исходящих сообщений и только
потом собственно создать в ней само сообщение и начинить его всей необходимой
информацией. В Simple MAPI все эти промежуточные шаги скрыты от разработчика. С
другой стороны MAPI 1.0 позволяет создавать сообщения в любой папке (да и не
только сообщения, а объекты календаря, задачи и т.д.). Таким образом, взамен
простоте использования появляются новые возможности.
Интерфейс MAPI 1.0, в отличие от Simple MAPI
можно использовать при создании служб Windows NT. Это очень полезное свойство
позволяет создавать различного рода почтовые мониторы. Типичная задача почтового
монитора может заключаться в сканировании почтового ящика пользователя на
предмет поступающей в него корреспонденции, ее разбор, анализ и последующие
действия по результатам этого анализа.
Отдельного обсуждения заслуживает такая
возможность MAPI 1.0 как создание всевозможных расширений (extensions) к
клиентским программам почтовой системы MS Exchange Server (MS Outlook или MS
Exchange Client). Расширения позволяют автоматизировать различные функции
обработки сообщений, не реализованные в базовом наборе функций клиентской
программы. В частности, механизм расширений позволяет создавать модули для
обработки входящих сообщений, так называемые правила (rules), добавлять к
клиентской программе дополнительные команды и пункты меню, а также обработчики
событий, изменяющие поведение системы при определенных событиях и многое другое.
Интерфейс CDO (Collaboration Data Objects),
ранее известный как OLE Messaging и Active Messaging представляет собой
библиотеку, обеспечивающую доступ приложений к несколько ограниченному набору
функция MAPI 1.0 через вызовы Automation. Функции работы с сообщениями могут
быть встроены в приложения, созданные с помощью любого средства разработки,
являющегося контроллером Automation. К таковым относятся C/C++, Visual Basic,
Visual Basic for Applications, VBScript, Javascript. Использование CDO
существенно упрощает разработку приложений, работающих с электронной почтой,
вместе с тем оставляя разработчику широкие возможности MAPI. Наибольшее
применение CDO находит в скриптовых языках. Так, например, в комбинации с APS
использование CDO позволяет достаточно легко создать почтового Web-клиента.
Итак, мы кратко рассмотрели 3 программных
интерфейса, позволяющих встраивать в приложения на платформе Windows
функциональность для работы с электронной почтой. У каждого из них есть свои
преимущества и недостатки. Ничего универсального не существует - окончательный
выбор того или иного средства зависит от конкретной задачи и является
прерогативой разработчика. Более подробную информацию на эту тему можно получить
на http://msdn.microsoft.com/library/psdk/mapi/.
Языки программирования: разное
|