9

Отправка почты в VB.NET.

13 февраля 2009 года

В двух словах, а точнее в трёх, о том, как отправлять почту в 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 секунд) и можно отправлять сообщение :-)

 

На этом у меня всё — удаляюсь, пока не появился всезнающий Зимин :-) 

Метки: , , , ,

9 комментариев к записи «Отправка почты в VB.NET.»

  1. Никита Зимин,

    А я бдю… и бдя моя ужасна…

    Ещё забыли System.Web.Mail.

    Из перечисленных способов третий для дотнета наиболее естественнен. Стоит ещё упомянуть, что можно задать client.Credentials либо UseDefaultCredentials, чтобы авторизоваться на сервере. Глядишь, и 300 секунд ждать не придётся.

    Ещё у вас dispose стоит без try..catch, а Send() может кучу исключений бросать.

  2. olegvv,

    Ай, Никита! Ай, молодца! ;)

  3. mkp,

    [cite] "Ещё забыли System.Web.Mail. " [/cite]

    Нет, не забыл :-)
    Я не стал его рассматривать в виду того, что этот способ устарел. Собственно, Microsoft рекомендует использовать System.Net.Mail. Подробнее здесь http://msdn.microsoft.com/en-us/library/system.web.mail.aspx

  4. egor.danilov,

    Сбегал за попкорном. Второй раунд будет, Никита? ;)

  5. Никита Зимин,

    Да вроде бы всё сказал чего хотел. Можно было ещё к стилистике кода придраться, но смысл?..

  6. Aidar ,

    а можно ли в варианте 2, не сразу отправлять сообщение а открыть его?

  7. PriZrak,

    Перепробовал все примеры, всё время пишет "Сбой при отправке сообщения электронной почты."… Может это потому что я сижу через спутниковый интернет? Тут прокси, порт и т.д. есть……. Если кто знает в чем дело, help please…

  8. dan,

    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]

  9. dan,

    примерчик на картинке не скинете?

Оставить комментарий