Почему не работает КомандаСистемы при вызове ImageMagick из 1С и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с внешним программным обеспечением разработчики часто сталкиваются с ситуацией, когда консольная команда отлично выполняется вручную через командную строку Windows (CMD), но отказывается работать при вызове из кода 1С через функцию КомандаСистемы или ЗапуститьПриложение. Типичным примером является работа с популярной утилитой для обработки изображений ImageMagick.

В этой статье мы подробно разберем, почему возникает данная проблема, проанализируем неочевидные системные механизмы взаимодействия платформы 1С с операционной системой и рассмотрим несколько надежных способов реализации этой задачи, включая штатные механизмы современных версий платформы 1С:Предприятие.

Выясняем причины: почему утилита «молчит» при запуске из 1С

Когда мы запускаем команду в интерактивном режиме командной строки, операционная система использует окружение текущего пользователя, его права, текущую кодовую страницу и настроенные системные пути. При вызове этой же команды из 1С контекст выполнения кардинально меняется. Выделим основные технические причины сбоев:

  1. Отсутствие путей в системной переменной PATH. Если при установке ImageMagick не был отмечен флаг добавления исполняемых файлов в переменные среды (Add application directory to your system path), операционная система просто не сможет найти файл magick.exe. Когда запуск происходит из рабочей директории платформы 1С (обычно это папка bin), система ищет утилиту именно там и, не найдя ее, прекращает работу.
  2. Конфликт имени convert.exe. В старых версиях ImageMagick ключевой командой для преобразования файлов была convert. Однако в операционной системе Windows (в каталоге System32) уже присутствует стандартная системная утилита convert.exe, предназначенная для конвертации файловой системы дисков из FAT в NTFS. При неявном вызове Windows пытается запустить именно системную утилиту, которая требует повышенных прав администратора. Это объясняет, почему запуск 1С от имени администратора временно «маскировал» проблему, хотя сама конвертация картинок все равно не происходила.
  3. Права доступа серверных процессов. Если код выполняется на стороне сервера 1С (в клиент-серверном варианте базы данных), то процесс запускается от имени системного пользователя (например, USR1CV8). У этого пользователя по умолчанию нет прав на запись в каталог C:\Program Files или в профили других пользователей на диске C:\.
  4. Проблема кодировки и спецсимволов. Пути к файлам, содержащие кириллические символы (например, папка пользователя C:\Users\Мой\AppData...), при передаче в командный интерпретатор CMD могут искажаться из-за несовпадения кодовых страниц 1С (Windows-1251) и консоли по умолчанию (CP866).
  5. Динамические библиотеки (DLL). Утилита magick.exe зависит от множества внешних библиотек (кодеков), расположенных в ее каталоге установки. Если запустить программу без указания ее рабочего каталога, она может не найти свои библиотеки и завершить работу аварийно на самом старте, из-за чего окно консоли лишь на мгновение «мелькает» на экране.

Решение 1: Правильная настройка окружения и путей

Самый простой и быстрый способ решить проблему — убедиться, что операционная система корректно определяет исполняемый файл. Для этого выполним следующие действия:

  1. Переустановите ImageMagick, обязательно установив флажок «Add application directory to your system path» в процессе инсталляции. Это автоматически добавит путь к утилите (например, C:\Program Files\ImageMagick-7.1.0-Q16-HDRI) в системную переменную PATH.
  2. В коде 1С всегда указывайте полный путь к исполняемому файлу, избегая зависимости от системных переменных. Если путь содержит пробелы, его обязательно нужно экранировать кавычками.

Рассмотрим пример правильного формирования строки запуска с экранированием путей кавычками в 1С:


ИсполняемыйФайл = """C:\Program Files\ImageMagick-7.0.10-Q16-HDRI\magick.exe""";
ПараметрыЗапуска = " convert " + """" + ЭлементМассиваКартинок + """" + " -resize 50% ""C:\test\test_new.jpg""";
ПолнаяКоманда = ИсполняемыйФайл + ПараметрыЗапуска;

КомандаСистемы(ПолнаяКоманда);

Решение 2: Переход на ЗапуститьПриложение с параметрами

Использование метода КомандаСистемы не всегда удобно, так как оно принудительно открывает черное окно консоли Windows. Более гибким решением является метод ЗапуститьПриложение. Он позволяет запускать внешние программы асинхронно или синхронно, скрывать окно выполнения и указывать рабочий каталог для корректной загрузки DLL-библиотек утилиты.

Разберем пример запуска приложения с ожиданием завершения процесса и скрытием окна консоли:


ПутьКПрограмме = "C:\Program Files\ImageMagick-7.0.10-Q16-HDRI\magick.exe";
РабочийКаталог = "C:\Program Files\ImageMagick-7.0.10-Q16-HDRI\";

// Формируем параметры для конвертации изображения
Параметры = "convert """ + ПутьКИсходномуФайлу + """ -resize 50% """ + ПутьКНовомуФайлу + """";

// Запускаем приложение в скрытом режиме (третий параметр - Ложь скрывает окно, четвертый - Истина активирует ожидание завершения)
ЗапуститьПриложение(ПутьКПрограмме + " " + Параметры, РабочийКаталог, Ложь, Истина);

Решение 3: Использование COM-объекта Wscript.Shell (Максимальный контроль)

Если вам требуется запускать утилиты абсолютно незаметно для пользователя и при этом получать код возврата операционной системы (чтобы понимать, успешно ли прошла обработка), мы рекомендуем использовать встроенный в Windows COM-объект Wscript.Shell.

Проанализируем пример функции, которая выполняет масштабирование картинки и возвращает результат выполнения операции:


Функция ИзменитьРазмерИзображенияЧерезШелл(ИсходныйФайл, ВыходнойФайл, ПроцентСжатия) Экспорт
    
    Шелл = Новый COMОбъект("Wscript.Shell");
    
    ПутьКMagick = """C:\Program Files\ImageMagick-7.0.10-Q16-HDRI\magick.exe""";
    СтрокаКоманды = ПутьКMagick + " convert """ + ИсходныйФайл + """ -resize " + ПроцентСжатия + "% """ + ВыходнойФайл + """";
    
    // Параметры метода Run: 
    // 1. Строка команды
    // 2. 0 - скрыть окно CMD (1 - показать)
    // 3. Истина - ждать завершения выполнения команды перед возвратом управления в 1С
    КодВозврата = Шелл.Run(СтрокаКоманды, 0, Истина);
    
    Если КодВозврата = 0 Тогда
        Возврат Истина; // Успешно обработано
    Иначе
        ЗаписьЖурналаРегистрации("ImageMagick", УровеньЖурналаРегистрации.Ошибка,,, 
            "Ошибка обработки файла. Код возврата системы: " + КодВозврата);
        Возврат Ложь;
    КонецЕсли;
    
КонецФункции

Решение 4: Использование прямого COM-объекта ImageMagick

Мало кто знает, что ImageMagick можно вызывать напрямую из 1С без запуска процессов операционной системы. Для этого при установке пакета ImageMagick на компьютер или сервер необходимо выбрать опцию установки COM-объекта (динамической библиотеки ActiveX). Это исключает проблемы с правами запуска командного интерпретатора и избавляет от необходимости парсить строки с кавычками.

Посмотрим на пример работы с COM-объектом:


Попытка
    // Создаем объект COM-интерфейса ImageMagick
    ИмиджМаджик = Новый COMОбъект("ImageMagickObject.MagickImage.1");
    
    // Вызываем метод конвертации напрямую через параметры COM-объекта
    ИмиджМаджик.Convert(ЭлементМассиваКартинок, "-resize", "50%", "C:\test\test_new.jpg");
    
    Сообщить("Изображение успешно обработано!");
Исключение
    Сообщить("Ошибка вызова ImageMagick через COM-объект: " + ОписаниеОшибки());
КонецПопытки;

Решение 5: Современная альтернатива без стороннего ПО (с версии 1С 8.3.15)

Если перед вами стоит задача простого изменения размера изображений, изменения формата (например, конвертация из PNG в JPG) или поворота картинки, то начиная с версии платформы 1С:Предприятие 8.3.15, больше нет необходимости устанавливать внешние утилиты вроде ImageMagick.

В платформу был добавлен мощный встроенный объект ОбработкаКартинок, работающий как на клиенте, так и на сервере (в том числе под управлением ОС Linux). Рассмотрим, как решить исходную задачу автора темы встроенными средствами 1С:


// Шаг 1. Загружаем исходное изображение из файла в объект "Картинка"
ИсходнаяКартинка = Новый Картинка("C:\test\test.jpg");

// Шаг 2. Инициализируем объект для обработки графики
Обработка = Новый ОбработкаКартинок;

// Шаг 3. Добавляем операцию масштабирования. 
// Первый параметр - Ширина, второй - Высота. 
// Если один из параметров Неопределено, пропорции сохраняются автоматически.
// Можно также использовать процентное соотношение.
Обработка.Добавить(МетодОбработкиКартинки.Масштабировать(Неопределено, 50)); // Уменьшаем размер наполовину

// Шаг 4. Применяем изменения к нашей картинке
РезультатОбработки = Обработка.Выполнить(ИсходнаяКартинка);

// Шаг 5. Записываем полученный результат на диск в новый файл
РезультатОбработки.Записать("C:\test\test_new.jpg");

Резюме и рекомендации

Подводя итоги, при возникновении ошибок запуска внешних консольных программ из 1С, рекомендуем придерживаться следующего алгоритма проверки:

← На главную