При работе в терминальном режиме (RDP или RemoteApp) системные архитекторы часто сталкиваются с проблемой «разрыва» среды. 1С:Предприятие выполняется на мощном сервере, а привычный пользователю почтовый клиент (MS Outlook или Thunderbird) со всеми архивами и настройками находится на локальном компьютере. Штатные средства 1С по отправке почты часто не удовлетворяют бизнес-требованиям: либо они перегружают базу данных хранением тяжелых писем, либо не позволяют пользователю комфортно отредактировать письмо перед отправкой в привычном интерфейсе. Рассмотрим, как наладить мост между сервером и клиентом для бесшовной отправки документов.
Многие типовые конфигурации на обычных формах, такие как Управление производственным предприятием или Комплексная автоматизация 1.1, имеют встроенный почтовый клиент. Однако его использование в среде RDP сопряжено с рядом трудностей. Во-первых, если отправлять почту напрямую с сервера через SMTP, пользователь лишается возможности увидеть отправленное письмо в папке «Отправленные» своего локального Outlook. Во-вторых, хранение истории переписки в базе 1С приводит к взрывному росту объема таблиц Email и вложений. Проанализируем ситуацию: нам нужно, чтобы 1С подготовила файл (счет или акт), а локальный компьютер пользователя «подхватил» его и открыл в окне нового письма.
Это одно из самых надежных решений, которое успешно внедряется на практике. Суть заключается в разделении задачи на два этапа: генерация файла письма на сервере и его перехват специальной программой-агентом на стороне клиента.
Шаг 1: Подготовка данных в 1С. Вместо прямой отправки мы заставляем 1С формировать файл в формате .eml или .msg. Этот файл должен содержать адрес получателя, тему, текст и само вложение. Рассмотрим пример формирования структуры данных:
Процедура СформироватьИСохранитьПисьмо(ОбъектДокумент, АдресПолучателя)
// Создаем почтовое сообщение (внутренний объект 1С)
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Получатели.Добавить(АдресПолучателя);
Письмо.Тема = "Счет на оплату № " + ОбъектДокумент.Номер;
// Формируем печатную форму в PDF
ПутьКФайлу = "C:\Temp\Invoice_" + ОбъектДокумент.Номер + ".pdf";
ОбъектДокумент.ПолучитьПечатнуюФорму().Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.PDF);
// Добавляем вложение
Письмо.Вложения.Добавить(ПутьКФайлу);
// Сохраняем как EML во временную сетевую папку
// Имя файла должно быть уникальным для пользователя
ИмяФайлаПисьма = "\\Server\MailExchange\" + ИмяПользователя() + "_mail.eml";
Письмо.Записать(ИмяФайлаПисьма);
КонецПроцедуры
Шаг 2: Работа клиентского брокера. На локальном компьютере пользователя запускается небольшое приложение (написанное, например, на Delphi, C# или Python), которое с определенной периодичностью опрашивает сетевую папку. Как только в папке появляется файл, имя которого начинается с логина текущего пользователя, брокер забирает его и выполняет системную команду открытия файла. В ОС Windows файлы .eml по умолчанию ассоциированы с установленным почтовым клиентом. Таким образом, у пользователя мгновенно «всплывает» окно Outlook с уже заполненными данными.
Если сетевые задержки велики или нет возможности организовать общую сетевую папку, разберем более продвинутый метод — использование виртуальных каналов RDP. Это позволяет передавать данные напрямую внутри RDP-пакета без использования протоколов SMB/HTTP.
Для реализации этого метода потребуется создание двух компонент:
Преимущество этого подхода в том, что нам не нужно знать IP-адрес клиента или настраивать права на папки. Данные передаются в контексте текущей сессии. 1С вызывает метод компоненты ПередатьПисьмоНаКлиент(ДанныеФайла), а локальный модуль принимает массив байтов и инициирует открытие почтовика через ShellExecute.
Выясним причину, по которой пользователи часто отказываются от прямой отправки: им нужно «дописать пару слов». Это можно реализовать через синхронизацию черновиков. Почти все современные почтовые серверы поддерживают IMAP4.
Алгоритм действий следующий:
Посмотрим на пример кода для работы с черновиками (требуется использование библиотек, поддерживающих расширенный IMAP, так как встроенный ИнтернетПочта в старых версиях 1С ограничен в части работы с папками):
// Псевдокод взаимодействия через внешнюю библиотеку
Почта = Новый Объект("MailLibrary.ImapClient");
Почта.Connect("imap.yandex.ru", 993, Истина);
Почта.Login(Логин, Пароль);
Почта.SelectFolder("Drafts");
Почта.AppendMessage(ТекстПисьмаВФорматеMime);
Почта.Disconnect();
Проанализируем самый простой способ передачи файла без создания сложных брокеров. В настройках RDP-подключения (вкладка «Локальные ресурсы») можно включить проброс дисков. В этом случае внутри сессии 1С диски пользователя видны по путям вида \\tsclient\C.
Мы можем программно сохранить сформированный документ прямо в папку автозагрузки или специальный скрипт на стороне клиента:
\\tsclient\C\1C_Exchange\send.eml.FileSystemWatcher.Start-Process "C:\Program Files\Microsoft Office\Office16\OUTLOOK.EXE" -ArgumentList "/eml", "$Path".Выбор конкретной реализации зависит от технической инфраструктуры предприятия:
EWS (Exchange Web Services) для прямой записи в черновики. Это наиболее чистое решение, не требующее стороннего ПО на компьютерах пользователей.Важным моментом является обработка ошибок. Всегда предусматривайте ситуацию, когда локальный почтовый клиент занят или недоступен. В таких случаях 1С должна выдавать информативное сообщение пользователю о том, что файл подготовлен, но не смог быть передан в Outlook, и предлагать открыть папку с файлом вручную для ручного перетаскивания.