При разработке сложных печатных форм в 1С программисты часто сталкиваются с ситуацией, когда стандартных средств платформы недостаточно. Типичный пример — необходимость конвертации PDF-файла в картинку для последующего вывода в ТабличныйДокумент. Основная сложность заключается в том, что печать в современных конфигурациях (особенно на базе БСП) происходит в модуле менеджера на стороне сервера, а внешние утилиты или пути к файлам часто доступны только на стороне клиента. В этой статье мы подробно разберем, почему метод ЗапуститьПриложение() не работает так, как ожидается, и рассмотрим эффективные стратегии решения этой задачи.
Прежде всего, проанализируем ситуацию. Когда код выполняется в модуле менеджера, он работает в контексте службы сервера 1С:Предприятие. Попытка вызвать ЗапуститьПриложение() с путем вроде "C:\Program Files\MyApp\app.exe" приведет к тому, что система будет искать этот файл на физическом сервере, а не на компьютере пользователя. Кроме того, серверная служба обычно работает под технической учетной записью (например, USR1CV8), у которой нет доступа к рабочему столу пользователя и его локальным папкам.
Рассмотрим по шагам основные способы обхода этого ограничения.
Самый прямой путь — сделать так, чтобы серверу не нужно было «обращаться к клиенту». Если вам необходимо использовать стороннюю утилиту (например, ImageMagick или Ghostscript для конвертации PDF), ее следует установить непосредственно на сервер 1С.
Важные нюансы при установке ПО на сервер:
PATH вступили в силу.Пример вызова на сервере может выглядеть так:
Команда = """" + ПутьКПрограммеНаСервере + """ convert """ + ПутьКФайлуPDF + """ """ + ПутьКРезультату + """";
ЗапуститьПриложение(Команда, , Истина); // Ждем завершения выполнения
Если мы работаем с Библиотекой стандартных подсистем (БСП), то процесс формирования печатной формы можно перехватить на клиенте до того, как управление уйдет на сервер. Проанализируем, как это сделать без «хаков».
Выясним причину: модуль менеджера вызывается из общей формы печати. Мы можем вмешаться в процесс в модуле команды печати или в процедуре УправлениеПечатьюКлиент.ВыполнитьКомандуПечати.
Алгоритм действий:
ЗапуститьПриложение().ВременноеХранилище с помощью метода ПоместитьВоВременноеХранилище().АдресХранилища в параметры печати.ТабличныйДокумент.Рассмотрим пример кода на клиенте:
// На клиенте
АдресКартинки = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ПутьККонвертированнойКартинке));
ПараметрыПечати.Вставить("АдресКартинки", АдресКартинки);
// Далее вызываем стандартную печать БСП, передавая эти параметры
Если база использует Систему взаимодействия, мы можем организовать обратную связь «Сервер -> Клиент». Это позволяет серверу отправить запрос клиентскому приложению на выполнение определенного действия.
Проанализируем схему:
ПриПолученииСообщения.ЗапуститьПриложение().Это сложный, но наиболее гибкий путь для асинхронной работы.
Начиная с версии платформы 8.3.16, в 1С появился встроенный объект ДокументPDF. Разберем, как он может помочь. Хотя он не умеет напрямую «рендерить» страницу в Картинку, он позволяет работать с метаданными документа прямо на сервере без вызова внешних приложений.
Однако для полноценной визуализации лучше использовать внешние компоненты (Native API), которые работают внутри адресного пространства сервера. Библиотеки вроде PDFium позволяют конвертировать PDF в массив байтов (изображение) без создания временных файлов и запуска сторонних .exe.
Пример структуры кода при использовании внешней компоненты:
ПодключитьВнешнююКомпоненту("ОбщийМакет.КонвертерPDF", "PDFLib", ТипВнешнейКомпоненты.Native);
Компонента = Новый("AddIn.PDFLib.Renderer");
КартинкаДанные = Компонента.RenderPageToPNG(ДанныеPDF, НомерСтраницы);
Рисунок = ТабДок.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
Рисунок.Картинка = Новый Картинка(КартинкаДанные);
На Windows-серверах эффективным решением является использование библиотек .NET через COM-обертку. Это позволяет избежать проблем с правами интерактивного запуска приложений. Мы можем использовать библиотеки Magick.NET или аналогичные.
Почему это лучше, чем ЗапуститьПриложение?
Когда мы вызываем внешний .exe, операционная система создает новый процесс, тратит ресурсы на его инициализацию и передачу параметров через командную строку. При использовании COM-объекта или Native API вызов происходит практически мгновенно, а данные передаются напрямую в памяти (через ДвоичныеДанные).
Мы рассмотрели несколько стратегий решения проблемы. Выбор конкретного метода зависит от ваших полномочий в системе:
USR1CV8.Помните, что архитектурно правильный код в 1С всегда разделяет подготовку данных (сервер) и взаимодействие с оборудованием или локальными файлами пользователя (клиент). Старайтесь избегать «хаков» с обработчиками ожидания, отдавая предпочтение штатным механизмам БСП и платформы.