В двух словах, а точнее в трёх, о том, как отправлять почту в WinAPI-приложениях.
1. Используем Simple MAPI, а в частности функцию MAPISendDocuments. Способ сгодится для работы с почтовыми клиентам, поддерживающими MAPI. Для этого необходимо загрузить mapi32.dll, задекларировать функцию MAPISendDocuments и вызвать ее с нужными нам параметрами. Выглядит это так:
Private Declare Function MAPISendDocuments Lib "mapi32.dll" Alias "MAPISendDocuments" (ByVal hwnd As Integer, ByVal lpszDelimChar As String, ByVal lpszFullPaths As String, ByVal lpszFileNames As String, ByVal nShowCmd As Integer) As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, Button1.Click
Try
Dim int As Integer = MAPISendDocuments(0, ";", "c:\ws2msg.txt", "ws2msg.txt", 0)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Обратите внимание на некоторые параметры функции MAPISendDocuments:
lpszDelimChar —символ-разделитель имен вложенных файлов
lpszFullPaths —полный путь до вложенного файла
lpszFileNames — имя вложенного файла
При вызове функции откроется окно почтового клиента, являющегося клиентом по умолчанию. Всё просто и ясно. Недостаток один — функция является "устаревшей" (deprecated) и Microsoft не рекомендует ее использовать, т.к. возможно в будущих версиях Windows она не будет поддерживаться. Подробнее ….
2. Использование Collaboration Data Objects. Способ удобен тем, что библиотека CDO есть на любом компьютере, на котором установлена ОС Windows 2000 и старше. Необходимо лишь добавить reference на Microsoft CDO for Windows 2000 Library и Microsoft ActiveX Data Objects
2.5 Library (или старше). Следующий код наглядно показывает, как можно создать и отправить e-mail:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim oMsg As CDO.Message = New CDO.Message()
Dim iConfg As CDO.Configuration
Dim oFields As ADODB.Fields
Dim oField As ADODB.Field
iConfg = oMsg.Configuration
oFields = iConfg.Fields
oField = oFields("http://schemas.microsoft.com/cdo/configuration/sendusing")
oField.Value = 2 ' CDO.CdoConfiguration.cdoSMTPServer
oField = oFields("http://schemas.microsoft.com/cdo/configuration/smtpserver")
oField.Value = "mail.your-server.com" ' имя почтового сервера
oField = oFields("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate")
oField.Value = 0 ' без аутентификации
oFields.Update()
oMsg.Configuration = iConfg
oMsg.TextBody ="текст тела пиьсма"
oMsg.Subject = "текст заголовока пиьсма"
oMsg.From = "from@some-company.com"
oMsg.To = "to@next-company.com"
'Добавляем вложенный файл
oMsg.AddAttachment("c:\1.txt")
oMsg.Send()
oMsg = Nothing
iConfg = Nothing
oFields = Nothing
oField = Nothing
End Sub
Пример понятен без пояснений. Отмечу лишь, что можно использовать базовую аутентификацию (значение 1) или NTLM-аутентификацию (значение 2). В обоих этих случаях необходимо указывать дополнительные параметры, например:
oField = oFields("http://schemas.microsoft.com/cdo/configuration/sendusername")
oField.Value = "qwerty"
oField = oFields("http://schemas.microsoft.com/cdo/configuration/sendpassword")
oField.Value = "pas123"
Помимо этогоможно указать в качестве параметра номер порта, использование SSL и время тайм-аута.
3. Испольвание классов из пространства имен System.Net.Mail. Первоисходник здесь. Пример использования:
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
Dim client as New SmtpClient("mail.your-server.com")
Dim fromAdr As MailAddress = New MailAddress("from@some-company.com", "Mail system", System.Text.Encoding.UTF8)
Dim toAdr As MailAddress = New MailAddress("to@next-company.com")
Dim message As MailMessage = New MailMessage(fromAdr, toAdr)
message.Subject = "текст заголовка"
message.SubjectEncoding = System.Text.Encoding.UTF8
message.Body = "текст тела письма"
message.BodyEncoding = System.Text.Encoding.UTF8
Dim attach As New Attachment("c:\1.txt")
message.Attachments.Add(attach)
client.Send(message)
message.Dispose()
End Sub
Опять-таки, думаю, что комментарии излишни. Кстати, вам ничего мешает указать в качестве адреса отправителя практически любой адрес. Например support@yandex.ru или helpdesk@skyme.ru ;-)
P.S. Не стоит пугаться в случае получения ошибки типа "Server Greylisted for 300 seconds". Дело в том, что дабы убедиться, что вы не спам-бот, сервер отклоняет ваше первое посланное сообщение. Почтовый сервис, не являющийся спам-ботом, при первой недуачной попытке через некоторое время снова попытается отослать сообщение адресату. Таким образом вам достаточно подождать 5 минут (это и есть те самые 300 секунд) и можно отправлять сообщение :-)
На этом у меня всё — удаляюсь, пока не появился всезнающий Зимин :-)
Метки: cdo, e-mail, simple mapi, vb.net, windows
А я бдю… и бдя моя ужасна…
Ещё забыли System.Web.Mail.
Из перечисленных способов третий для дотнета наиболее естественнен. Стоит ещё упомянуть, что можно задать client.Credentials либо UseDefaultCredentials, чтобы авторизоваться на сервере. Глядишь, и 300 секунд ждать не придётся.
Ещё у вас dispose стоит без try..catch, а Send() может кучу исключений бросать.
Ай, Никита! Ай, молодца! ;)
[cite] "Ещё забыли System.Web.Mail. " [/cite]
Нет, не забыл :-)
Я не стал его рассматривать в виду того, что этот способ устарел. Собственно, Microsoft рекомендует использовать System.Net.Mail. Подробнее здесь http://msdn.microsoft.com/en-us/library/system.web.mail.aspx
Сбегал за попкорном. Второй раунд будет, Никита? ;)
Да вроде бы всё сказал чего хотел. Можно было ещё к стилистике кода придраться, но смысл?..
а можно ли в варианте 2, не сразу отправлять сообщение а открыть его?
Перепробовал все примеры, всё время пишет "Сбой при отправке сообщения электронной почты."… Может это потому что я сижу через спутниковый интернет? Тут прокси, порт и т.д. есть……. Если кто знает в чем дело, help please…
Service not available, closing transmission channel. The server response was: Cannot connect to SMTP server 64.95.64.197 (64.95.64.197:25), connect error 10060
[b][i][u]Что это такое?[/u][/i][/b]
примерчик на картинке не скинете?