При автоматизации бизнес-процессов часто возникает задача отправки электронных писем непосредственно из системы 1С. Один из классических способов сделать это на платформе Windows — использование COM-объекта CDO.Message. Однако разработчики могут столкнуться с ситуацией, когда код, прекрасно работающий на локальной машине, напрочь отказывается функционировать на сервере 1С, выдавая ошибку "Произошла исключительная ситуация (CDO.Message.1): The transport failed to connect to the server."
Проанализируем эту проблему. Чаще всего она возникает при переносе решения с 32-битной клиентской машины (например, с Windows XP или Windows 7) на 64-битный сервер (например, Windows Server 2008/2012/2016). Ошибка явно указывает на невозможность установить сетевое соединение с SMTP-сервером. Давайте разберемся в причинах и найдем решение.
Рассмотрим типичный код для отправки письма с вложением через CDO.Message, который вызывает проблему:
Процедура ОтправитьПисьмоCDO(АдресПолучателя, Тема, Текст, ФайлВложения) Экспорт
Попытка
oMail = Новый COMОбъект("CDO.Message");
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
// Настройки подключения к SMTP-серверу
oMail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing").Value = 2;
oMail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver").Value = "smtp.mail.ru";
oMail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport").Value = 465;
oMail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl").Value = true;
oMail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate").Value = 1;
oMail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusername").Value = "login@mail.ru";
oMail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword").Value = "password";
oMail.Configuration.Fields.Update();
// Формирование письма
oMail.To = АдресПолучателя;
oMail.From = """Имя отправителя"" <login@mail.ru>";
oMail.Subject = Тема;
oMail.TextBody = Текст;
// Добавление вложения
Если ЗначениеЗаполнено(ФайлВложения) Тогда
oMail.AddAttachment(ФайлВложения);
КонецЕсли;
Попытка
oMail.Send();
Исключение
Сообщить("Не удалось отправить сообщение!");
Сообщить(ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Первое, что нужно сделать, — это исключить базовые сетевые проблемы. Сама ошибка "The transport failed to connect to the server" говорит не о проблеме с аутентификацией или неправильно сформированным письмом, а о том, что на самом низком уровне не удалось установить TCP-соединение с SMTP-сервером. Для проверки выполним следующие шаги:
cmd).telnet для проверки доступности порта SMTP-сервера. Например, для mail.ru и порта 465 команда будет выглядеть так: telnet smtp.mail.ru 465.Если после выполнения команды экран становится черным (пустым), это означает, что соединение успешно установлено. Если вы получаете сообщение об ошибке подключения, значит, проблема в сетевых настройках (например, в корпоративном прокси или файрволе на уровне сети). Однако, как показывает практика, чаще всего telnet успешно соединяется, а код 1С — нет. Это подводит нас к основной причине.
Ключевое различие между выполнением кода на локальной машине и на сервере 1С заключается в контексте исполнения. На локальной машине код выполняется в процессе клиента 1С (1cv8c.exe). На сервере же он выполняется в рамках рабочего процесса сервера 1С — rphost.exe.
Серверные операционные системы и установленное на них ПО для обеспечения безопасности (антивирусы, брандмауэры) имеют гораздо более строгие политики, чем на клиентских машинах. Они по умолчанию могут блокировать любую подозрительную сетевую активность от серверных процессов, коим и является rphost.exe. Антивирус видит, что неизвестный ему процесс пытается установить исходящее соединение на внешний SMTP-сервер, и превентивно его блокирует.
Решение заключается в добавлении рабочего процесса сервера 1С в исключения антивируса и брандмауэра.
rphost.exe обычно находится в каталоге установки платформы 1С. Например: C:\Program Files\1cv8\8.3.20.1234\bin\rphost.exe. Точный путь можно посмотреть в диспетчере задач на сервере.rphost.exe.C:\Program Files\1cv8\...\bin\rphost.exe.После выполнения этих действий повторите попытку отправки письма из 1С. В большинстве случаев ошибка "The transport failed to connect to the server" будет устранена.
Хотя решение с настройкой исключений для CDO работает, оно имеет существенные недостатки: зависимость от COM-компонентов Windows и потенциальные проблемы с правами доступа и разрядностью (bitness). Более современным, надежным и кроссплатформенным решением является использование встроенных объектов 1С для работы с почтой.
Рассмотрим, как переписать наш пример с использованием объектов ПрофильИнтернетПочты и ИнтернетПочта.
Процедура ОтправитьПисьмо1С(АдресПолучателя, Тема, Текст, ФайлВложения) Экспорт
// Настраиваем профиль подключения
Профиль = Новый ПрофильИнтернетПочты;
Профиль.АдресСервераSMTP = "smtp.mail.ru";
Профиль.ПортSMTP = 465;
Профиль.ПользовательSMTP = "login@mail.ru";
Профиль.ПарольSMTP = "password";
Профиль.АутентификацияSMTP = СпособSMTPАутентификации.Login;
Профиль.ИспользоватьSSLSMTP = Истина;
// Создаем объект для работы с почтой
Почта = Новый ИнтернетПочта;
Попытка
Почта.Подключиться(Профиль);
Исключение
Сообщить("Не удалось подключиться к почтовому серверу!");
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
// Формируем сообщение
Сообщение = Новый ИнтернетПочтовоеСообщение;
Сообщение.Получатели.Добавить(АдресПолучателя);
Сообщение.Отправитель = "login@mail.ru";
Сообщение.ИмяОтправителя = "Имя отправителя";
Сообщение.Тема = Тема;
Сообщение.Тексты.Добавить(Текст, ТипТекстаИнтернетПочтовогоСообщения.ПростойТекст);
// Добавляем вложение
Если ЗначениеЗаполнено(ФайлВложения) Тогда
Сообщение.Вложения.Добавить(ФайлВложения);
КонецЕсли;
Попытка
Почта.Послать(Сообщение);
Исключение
Сообщить("Не удалось отправить сообщение!");
Сообщить(ОписаниеОшибки());
КонецПопытки;
Почта.Отключиться();
КонецПроцедуры
Преимущества этого подхода:
Таким образом, хотя проблема с CDO решаема, мы настоятельно рекомендуем для новых разработок использовать встроенные средства платформы 1С для работы с электронной почтой.