16+
ComputerPrice
НА ГЛАВНУЮ СТАТЬИ НОВОСТИ О НАС




Яндекс цитирования


Версия для печати

Модуль поиска не установлен.

Программирование электронной почты. Часть 1

21.01.2004

Павел Кондратьев

В связи с бурным развитием интернет-программирования поддержка сервиса электронной почты стала весьма распространенной задачей для программистов. К примеру, каждый уважающий себя сайт должен содержать раздел обратной связи с авторами странички с возможностью отправки письма непосредственно из Web. Не менее распространенной задачей является написание программ-рассылок, связанных с рекламной деятельностью...

Или, наоборот, может понадобиться создание антиспамерских программ, для написания которых необходимо знать устройство "врага" (то есть программ рассылки) изнутри. Иногда требуется реализовать обмен данными между двумя программами в асинхронном режиме, ЭП также подходит для этих целей. Хорошо это или плохо, но разговор пойдет только о программировании под Windows.

В принципе, большинство программистов, имея MSDN, за пять минут разберутся с подключением сервиса ЭП к своей программе, поскольку зачастую ничего кроме вызова стандартного окошка отправки письма и не требуется, однако если потребуется нечто большее (например, отправить письмо с определенного адреса, минуя окно диалога), сразу появляется множество технических проблем. Попробуем разобраться, как с ними бороться в той или иной ситуации.

Электронная почта (ЭП) появилась в 70-х годах прошлого века и до сих пор остается востребованной технологией, позволяющей асинхронно обмениваться сообщениями пользователям и программам как через Интернет, так и внутри локальных сетей. За время развития Интернета ЭП успела обрасти множеством дополнительных протоколов и форматов и, похоже, будет развиваться дальше.

Чтобы эффективно решить задачу доступа к ЭП в своей программе, необходимо понять основы устройства ЭП. ЭП представляет собой совокупность протоколов, регламентирующих обмен данными по сети, и программных средств, реализующих эти протоколы и предоставляющих пользователю соответствующие интерфейсы. Основными протоколами ЭП являются протоколы передачи (отсылки) и чтения писем, которые работают поверх TCP/IP. Для передачи сообщений по TCP-соединению подавляющее большинство программных средств пользуется протоколом SMTP - Simple Mail Transfer Protocol. Совокупность команд и кодов ответов для этого протокола изложена в документе RFC821. Для приема почтовых сообщений в Интернете обычно используется протокол POP3 (Post Office Protocol 3), см. RFC 1939. Оба протокола регламентируют последовательность команд клиента и откликов сервера. Все команды форматированы по определенным правилам (символ любой команды состоит из семи битов набора ASCII и является буквой, цифрой или знаком пунктуации).

В принципе, знания этих протоколов уже хватает, для того чтобы отправить или получить письмо. Например, зная последовательность вводимых команд, вы можете общаться с почтовым сервером (который, собственно, и будет их выполнять) через telnet. Клиент вводит команды для того, чтобы указать адрес получателя, тему письма, текст, или же, наоборот, скачать письмо, а сервер эти команды исполняет и возвращает код отклика. Обмен данными клиента и сервера происходит по TCP/IP через порт 25 для SMTP и порт 110 для POP3. Это основа. Такой обмен нам и необходимо запрограммировать. Конечно, нам не обязательно программировать на таком низком уровне, ведь существует большое количество готовых компонентов, которые все это умеют делать за вас, а все программирование при этом сводится к вызовам методов (функций) с определенными параметрами, задающими характеристики письма. Однако может так сложиться, что такие готовые компоненты по каким-то причинам вас не устроят, и было бы неплохо как раз-таки залезть на более низкий уровень и добавить недостающую функциональность. Поэтому еще об устройстве ЭП. Протоколы SMTP и POP3 рассмотрим позже, без них нам все равно не обойтись.

Все начинается с электронного адреса (EMail). Он регистрируется на почтовом сервере, где для каждого адреса заводится почтовый ящик. Все приходящие на ваш адрес письма будут храниться на сервере, пока вы их оттуда не скачаете. Помимо этого, ваш адрес регистрируется на DNS-серверах для того, чтобы ваш адрес смог отыскать почтовый сервер отправителя. При отправке письмо проходит цепочку серверов, пока не отыскивается нужный адрес (иногда проходит несколько часов, пока нужный адрес не отыщется на одном из таких серверов). При получении письма клиент авторизируется, заходит в свой почтовый ящик и получает письмо. При этом письмо может остаться на сервере, а может переместиться на жесткий диск вашего компьютера, в зависимости от настроек почтового агента, которым вы пользуетесь. Почтовый агент (ПА), собственно, и реализует протоколы SMTP и POP3, это он посылает за вас соответствующие команды на почтовый сервер, предоставляя вам, в свою очередь, удобный интерфейс для создания и чтения писем. К стандартным функциям почтовых агентов можно отнести следующие: ведение адресной книги, задание стандартных атрибутов письма + вложение файлов, поддержка различных кодировок, интерпретация полученных прикрепленных медиа-файлов. Кроме того, почтовый агент должен отслеживать наличие соединения с Интернетом.

Исходя из вышесказанного, необходимо понимать, как в системе разделяются функции по обработке ЭП. Самым простым вариантом для пользователя и программиста будет тот случай, когда заботу о доставке данных возьмет на себя система. Собственно, так фирма Microsoft и поступила. В системе устанавливается почтовый агент и назначается агентом, используемым по умолчанию (к примеру, Outlook Express). При любом обращении к сервису ЭП в системе вызывается этот почтовый агент. (Информация о том, какой агент используется по умолчанию, хранится в системном реестре в разделе HKEY_LOCAL_ MACHINE\SOFTWARE\Clients\mail). Обращаю ваше внимание на то, что при работе с почтой через web функции ПА берет на себя сам сервер (такой как mail.ru), предоставляющий почтовые услуги, и весь процесс происходит без участия вашей локальной почтовой системы. Локальный ПА отслеживает наличие соединения с Интернетом и в определенные моменты времени (в зависимости от настроек) отсылает уже написанные письма, находящиеся в системной папке "исходящие", и принимает новые письма, помещая их в системную папку "входящие". И тут сразу возникает вопрос, как ПА хранит полученные письма и сможет ли их прочитать другой ПА, если мы захотим его заменить (например, поменяем "Microsoft Outlook" на "Bat")? Сможет, и вот почему. Для совместимости и стандартизации доступа приложений к ЭП Microsoft разработала набор интерфейсов, называемых MAPI (Messaging API). Архитектура MAPI описывает так называемую подсистему MAPI, которая обеспечивает взаимодействие клиентских приложений с различными службами почтовой системы, такими как служба хранения информации, служба адресной книги, служба транспорта и т.д. Итак, все ПА, которые предназначены для функционирования в Windows, должны поддерживать интерфейсы MAPI. С другой стороны, MAPI - это прикладной интерфейс, который был создан для того, чтобы разработчики на С, С++, Visual Basic или Visual Basic Script имели возможность добавлять в свои приложения функциональность для работы с электронной почтой. С точки зрения прикладной программы, подсистема MAPI - это набор динамических библиотек, содержащих функции и объектно-ориентированные интерфейсы, благодаря которым взаимодействуют клиентские и серверные части почтовых приложений. Это значит, что, если в системе функционирует почтовый агент, совместимый с MAPI (а их подавляющее большинство), то мы можем обратиться к нему через MAPI-интерфейс посредством некоторых вызовов и выполнить нужные нам операции, например, сформировать и отправить письмо. При этом мы обращаемся к текущему ПА и всего лишь "поручаем" ему выполнить необходимые действия, а как он это сделает, зависит лишь от его настроек. Отсюда и минусы, и плюсы. Скажем, если по умолчанию в системе установлен Outlook Express, то каждый раз при вызове из своей си-программы функции:

MAPISendMail(pSession, 0, &pMessage, 0, 0); //отправить письмо pMessage

вы будете видеть окно статуса приема/передачи Outlook Express поверх вашей программы. Лично меня это иногда раздражает, тем более, что это окошко нередко перехватывает фокус. Или, например, если вы включили в своем ПА поддержку электронной подписи, то любое исходящее письмо, отправляемое вашей программой, будет также подписано. Для simple MAPI (далее мы обсудим версии MAPI), устанавливаемого с Outlook Express, программно отсылать письма можно только с того адреса, который выставлен в ПА по умолчанию. Почему-то Microsoft решила, что нам должно хватать этого одного адреса для всех случаев жизни :)

Вывод: MAPI ограничивает наши возможности программирования набором своих интерфейсов и функциональными возможностями ПА. Теперь перечислим плюсы. Вы всегда найдете отправленное вашей программой письмо в "исходящих" или "отправленных", а полученное во "входящих" ПА, вы имеете доступ к адресной книге и вам не нужно заботиться о подключении к Интернету (ПА сам все отправит при первом подключении) и еще много чего. Итак, если все же MAPI вас не устраивает, то добро пожаловать в раздел "программирование WinSock". Этот компонент позволяет снять ограничения, налагаемые MAPI, и с его помощью, зная соответствующие протоколы, вы даже можете написать свой почтовый агент. А сейчас о программировании MAPI.

MAPI

Для программирования MAPI существуют различные клиентские прикладные программные интерфейсы, среди которых следует выделить в первую очередь Simple MAPI, MAPI и CDO. Надо сказать, что в MSDN вы найдете множество информации на эту тему в разделе Platform SDK docs \ Messaging and collaboration services.

Simple MAPI предоставляет в распоряжение разработчиков всего 12 простейших функций. Они позволяют выполнять такие действия, как "сформировать сообщение", "указать адрес получателя", "отправить", "получить". Причем все операции с сообщениями можно производить только в рамках одной папки, являющейся папкой для входящих сообщений текущего контейнера доставки. Разработчик не имеет доступа к полной структуре папок почтового сервера, то есть может контролировать сообщение лишь до тех пор, пока пользователь не переместит его из папки "Inbox" в какую-либо другую. Simple MAPI позволяет запрограммировать две основные функции электронной почты - отправку и прием сообщений для текущей учетной записи. Зачастую это вся функциональность, необходимая приложению для работы с электронной почтой. Типичными примерами использования Simple MAPI являются интернет-приложения, предлагающие отправить письмо из Web.

Открыть окно ПА для создания нового сообщения можно и с помощью системной команды "mailto:", доступной для исполнения в bat-файлах. Или можно поместить на веб-страницу (в теге <A href=...>) гиперссылку следующего вида:

mailto:email1;email2&cc=email3?subject= Subject%20text&body=Body%0dText.

Определения всех функций, структур и констант Simple MAPI для С-программирования можно найти в файле MAPI.H, входящем в состав Microsoft Visual Studio. Его аналогом для Visual Basic является файл MAPI.BAS (MAPIVB.BAS). Сами функции находятся в динамической библиотеке MAPI.DLL (MAPI32.DLL), где хранится вся функциональность MAPI, в том числе и extended MAPI. Simple MAPI не позволяет конфигурировать профайлы и отправляет сообщения только с учетной записи, выставленной по умолчанию. Как правило, Simple MAPI входит в состав клиентских почтовых программ, причем не только работающих в архитектуре "клиент-сервер" (MS Outlook, MS Exchange Client), но и обычных (MS Outlook Express, Eudora Pro, The Bat!).

Пример кода на С++ :

//Установить сессию (авторизироваться)
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);

Кроме того, Simple MAPI реализуют некоторые готовые компоненты, например, Microsoft MAPI Controls.

Microsoft MAPI Controls (MSMAPI32.ocx)

Данный компонент представляет собой COM-сервер и содержит два объекта: MAPISession и MAPIMessage. Первый содержит методы для установки соединения (инициализации сессии), второй предназначен для работы с самими почтовыми сообщениями.

Пример использования MAPI Controls на VB6.

Подключите компонент в проект и расположите на форме два невидимых компонента MAPISession и MAPIMessage. Если вам в программе не нужна форма, сделайте ее также невидимой.

Установка соединения. Для открытия сессии используется метод SignOn. Для отключения соответственно SignOff.

Private Sub Form_Load() MAPISession1.SignOn MAPISession1.SignOff End Sub

Свойства MAPISession.UserName и MAPISession. Password задают имя и пароль к требуемому профайлу, если в качестве почтовой системы используется Microsoft Mail. Если же вы пользуетесь Outlook, эти свойства ни на что не влияют, а в качестве активной учетной записи используется учетная запись, выставленная по умолчанию.

Private Sub Form_Load()
MAPISession1.UserName = "MyName"
MAPISession1.Password = "MyPassword"
MAPISession1.SignOn
...
MAPISession1.SignOff
End Sub

Так устанавливается соединение с почтовым сервером. Теперь получим доступ к различным сервисам, доступным через MAPIMessages. Перед использованием MAPIMessages необходимо присвоить идентификатор открытой сессии:

MAPIMessages1.SessionID = MAPISession1.SessionID

Для чтения входящих писем используется метод Fetch, после вызова которого заполняется коллекция сообщений MAPIMessages1. После заполнения коллекции MAPIMessages содержит письмо с индексом, которое задает свойство: MAPIMessages1.MsgIndex

В следующем примере получим другую информацию о письмах, находящихся в папке "Входящие". Добавьте Listbox на форму и введите следующий код:

Private Sub Form_Load()
Dim i As Long
MAPISession1.DownLoadMail = True
MAPISession1.SignOn
MAPIMessages1.SessionID = MAPISession1.SessionID
MAPIMessages1.Fetch
If MAPIMessages1.MsgCount > 0 Then
For i = 0 To MAPIMessages1.MsgCount - 1
MAPIMessages1.MsgIndex = i
List1.AddItem "От:"
& MAPIMessages1.MsgOrigDisplayName & _
" Тема:" & MAPIMessages1.MsgSubject
Next
End If
MAPISession1.SignOff
End Sub

С помощью данного кода мы получим список всех заголовков писем из ящика "Входящие". Вы можете использовать MsgOrigAddress вместо MsgOrigDisplayName. В этом случае вы получите электронные адреса отправителей (вместо псевдонимов). Вы можете получить доступ и к другой информации, заложенной в письмах.

Например, MsgDateReceived содержит дату получения письма.

Создание письма

Для создания письма снова используется MAPIMessages. Перед отправкой нужно задать несколько необходимых параметров и, если нужно, присоединить файлы:

Private Sub Form_Load()
MAPISession1.SignOn
MAPIMessages1.SessionID = MAPISession1.SessionID
MAPIMessages1.Compose 'очистить буфер перед отсылкой
MAPIMessages1.RecipAddress = "bill@microsoft.com"
MAPIMessages1.MsgSubject = "Hello"
MAPIMessages1.MsgNoteText = "Срочно приезжай! Ждем."
'Присоединяем к письму два файла
MAPIMessages1.AttachmentIndex = 0
MAPIMessages1.AttachmentPathName = ("C:\file1.txt")
MAPIMessages1.AttachmentIndex = 1
MAPIMessages1.AttachmentPathName = ("C:\file2.txt")
MAPIMessages1.Send False
MAPISession1.SignOff
End Sub

Используя False в методе Send, вы запрещаете показ окна "Создание нового письма".

COM модель Outlook предоставляет интерфейсы для работы со стандартными объектами Outlook. Например, из VB6 можно подключить ссылку на Microsoft Outlook, создать объект Outlook.Application, установить сессию, создать объект Message, установить его свойства, отослать с помощью метода send и т.п. Интерфейс Outlook предоставляет богатые возможности по работе с папками, формами, контактами, но отсылка почты реализована также на уровне simple MAPI.

MAPI 1.0 - расширение MAPI (Extended MAPI). Дело в том, что Simple MAPI является упрощенным интерфейсом и накладывает серьезные ограничения на разработчика, как в плане функциональности, так и в плане производительности приложения. Преодолеть эти ограничения позволяет мощный программный интерфейс MAPI 1.0, который содержит более ста функций и нескольких десятков COM-интерфейсов, предоставляющих программистам на С++ (Delphi) богатый инструментарий для создания приложений, работающих с электронной почтой. Simple MAPI можно назвать оберткой MAPI 1.0, которая скрывает множество деталей и нюансов взаимодействия приложений с почтовыми системами. MAPI 1.0 предоставляет доступ к адресной книге, службе транспорта, структуре системных папок, короче говоря, предоставляет полный контроль над почтовой системой. С помощью MAPI 1.0 можно добавлять функциональность к почтовым агентам (например, добавлять формы к Outlook) или реально написать полноценный почтовый клиент. Однако программирование MAPI 1.0 довольно сложная задача, поскольку необходимо разбираться не только в тонкостях MAPI-интерфейсов, но и в особенностях COM-программирования на С++ или Delphi .

Интерфейс и базовые функции находятся в системной библиотеке MAPI32.DLL. В разделе системного реестра "HKEY_LOCAL_MACHINE\ SOFTWARE\Microsoft\Windows\Windows Messaging Subsystem" содержится информация о версиях MAPI, имеющихся в системе.

Необходимо отметить, что в Windows 95 подсистема MAPI входила в дистрибутив операционной системы, а в Windows 98 устанавливалась дополнительно с дистрибутивного диска, либо вместе с Outlook, Exchange (MAPI 1.0) или Outlook Express (simple MAPI). В Windows 2000 из MAPI присутствует только CDO для Windows 2000 (CDOSYS), и MAPI 1.0 необходимо ставить дополнительно, например с Microsoft Outlook, что не всех может устроить. В Windows ME и XP по умолчанию устанавливается Outlook Express, который устанавливает в систему simple MAPI. Кроме того, simple MAPI содержит Internet Explorer 5.0 и выше.

Это означает, что программа, разработанная для MAPI 1.0, не на всех платформах сможет корректно функционировать без установки необходимых программных комплексов. Согласитесь, не очень корректно требовать от пользователя вашей программы установить Microsoft Outlook вместо его почтового агента, если у него операционная система - Win2000.

А вот так на C++ будет выглядеть пример программы, отсылающей письмо посредством MAPI 1.0:

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 (:);

Исходя из всего вышесказанного, программирование под MAPI 1.0 сложное и не очень благодарное занятие для тех, кто все же хочет изучить MAPI 1.0, отсылаю к MSDN, благо, там содержится исчерпывающая информация по этой теме.

CDO (Collaboration Data Objects), представляет собой нечто среднее между simple и extended MAPI, так как обеспечивает доступ к несколько ограниченному набору функций MAPI 1.0 через вызовы Automation. Функции работы с сообщениями могут быть встроены в приложения, созданные с помощью любого средства разработки, являющегося контроллером Automation. К таковым относятся C/C++, Visual Basic, Visual Basic for Applications, VBScript, Javascript. Использование CDO существенно упрощает разработку приложений, работающих с электронной почтой, вместе с тем оставляя разработчику достаточно широкие возможности MAPI. Наибольшее применение CDO находит в скриптовых языках.

Пример создания нового письма:

Dim objSession As Object ' Dim objSession As MAPI.Session
Dim objMessage As Object ' Dim objMessage As Message
Dim objOneRecip As Object ' Dim objOneRecip As Recipient
' создать объект "сессия"
Set objSession = CreateObject ("MAPI.Session")
' установить сессию и авторизироваться
objSession.Logon profileName:="Jane Doe", profilePassword:="my_pword"
' создать новое сообщение
Set objMessage = objSession.Outbox. Messages.Add
objMessage.Subject = "Sample Message"
objMessage.Text = "This is some sample message text."
' создать получателя
Set objOneRecip = objMessage.Recipients.Add
objOneRecip.Name = "John Doe"
objOneRecip.Type = CdoTo
objOneRecip.Resolve
' отправить сообщение
objMessage.Update
objMessage.Send showDialog:=False
MsgBox "The message has been sent"
' завершить сессию
objSession.Logoff

Одним из существенных преимуществ CDO перед Simple MAPI является объектное представление почтового сообщения на уровне MIME-сущностей (свойство Fields объекта Message). Это значит, что можно получить доступ к отдельным частям почтового сообщения и обрабатывать их так, как требуется вашей программе.

Основной версией CDO, описанной в MSDN и технической литературе и доступной для любых платформ является CDO 1.21. По неизвестным причинам Microsoft более не распространяет CDO 1.21, и единственный путь установить этот компонент - это инсталлировать Microsoft Outlook 98 или Exchange 5.5. Без них вы не сможете пользоваться CDO, даже если найдете и вручную зарегистрируете библиотеки MAPI32.dll, CDOHTML.dll и EXCHMEM.DLL. Интерфейс CDO произошел от OLE Messaging и Active Messaging (под Exchange 5.0), который, по сути, был COM-оберткой для MAPI.

С появлением Exchange 5.5 Microsoft сменил название библиотеки на CDO (Collaboration Data Object). Функциональность же принципиально не изменилась. Для доступа к компонентам SMTP и NNTP, входящим в состав IIS 4.0, появилась библиотека CDONTS - специализированное подмножество CDO. А вместе с Windows 2000 вышла библиотека CDO 2.0 или CDO for Windows 2000. Основой для нее явились принципиально новые решения: поддержка Internet-стандартов и стандартизация доступа к данным через OLE DB/ADO-интерфейс. Известно, что операционная система Windows 2000 активно использует эту библиотеку для своих задач. CDO 2000 может функционировать только на платформе Windows 2000, поэтому его нельзя использовать для написания почтовых программ, предназначающихся для других платформ. С выходом Exchange 2000 в свет появилось еще несколько библиотек CDO - 3.0 или CDO for Exchange 2000, CDO for Exchange Management и CDO Workflow Objects for Exchange.

Пример использования CDONTS на VBScript:

Set objNewMail = CreateObject ("CDONTS.NewMail")
'Присоединяем файл
objNewMail.AttachFile "\\server\Documents\ MyDoc.doc", "MyFile.Doc"
'Отсылаем письмо
objNewMail.Send "Generator", "someone@microsoft.com", "Subject", "The message body", 0
Set objNewMail = Nothing

Программирование электронной почты. Часть 2
Программирование электронной почты. Часть 3



статьи
статьи
 / 
новости
новости
 / 
контакты
контакты