Почему возникает ошибка «Класс не зарегистрирован» при вызове COM-объекта ImageMagick из 1С и как её исправить?

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

При попытке инициализировать COM-объект ImageMagick из платформы 1С с помощью конструктора Новый COMОбъект("ImageMagickObject.MagickImage.1") разработчики часто сталкиваются с ошибкой -2147221164(0x80040154): Класс не зарегистрирован. При этом аналогичный код в файле VBScript на том же компьютере может выполняться без каких-либо сбоев.

Рассмотрим подробно причины возникновения этой проблемы и разберем практические способы её решения.

Выясняем причину ошибки

Разберем ситуацию, почему один и тот же код работает из VBScript, но выбивает ошибку в 1С:

  1. Несовпадение разрядности (32 bit и 64 bit): В 64-разрядной системе Windows по умолчанию файлы .vbs запускаются через 64-битный интерпретатор. Если на сервере или рабочей станции установлена 64-битная версия ImageMagick, то 64-битный VBScript легко находит зарегистрированный COM-объект. Однако если клиент 1С является 32-битным (x86), он запускается в подсистеме WOW64. 32-битное приложение 1С не может напрямую загрузить 64-битную внутрипроцессную библиотеку (In-Process DLL ImageMagickObject.dll), из-за чего система выдаёт ошибку 0x80040154.
  2. Почему с Excel всё работает: Приложения MS Office (например, Excel) работают как отдельные приложения (Out-of-Process COM-серверы), обмен с которыми идет через внешние механизмы межпроцессного взаимодействия Windows. Библиотека ImageMagickObject же представляет собой In-Proc DLL, требовательную к совпадению разрядности с процессом-хостом.
  3. Особенности ImageMagick 7+: В современных версиях ImageMagick 7 компонента ImageMagickObject.dll признана устаревшей и по умолчанию не всегда регистрируется или поставляется в дистрибутиве.

Проверить это поведение можно, запустив ваш тестовый VBScript через 32-битный хост из папки C:\Windows\SysWOW64\wscript.exe. Вы увидите ту же ошибку, что и в 1С.

Способ 1. Настройка COM+ (Службы компонентов) для объединения разрядностей

Если требуется использовать именно COM-объект ImageMagick из 32-битного клиента 1С при установленной 64-битной компоненте, можно настроить вызов библиотеки через суррогатный процесс dllhost.exe в COM+.

Разберем процесс настройки по шагам:

  1. Откроем оснастку Службы компонентов (нажав Win + R и введя comexp.msc).
  2. Перейдем в раздел Компьютеры > Мой компьютер > Приложения COM+.
  3. В контекстном меню выберем Создать > Приложение. В мастерe укажем «Создать новое приложение», зададим имя (например, ImageMagickCOM) и выберем тип Серверное приложение (Server Application).
  4. Укажем учетную запись, от имени которой будет запускаться процесс.
  5. В созданной папке приложения перейдем к ветке Компоненты, вызовем контекстное меню, выберем Создать > Компонент и импортируем уже зарегистрированный 64-битный класс ImageMagickObject.MagickImage.1.

После этой настройки 32-битный процесс 1С сможет обращаться к 64-битному COM-объекту через запущенный суррогатный процесс Windows.

Способ 2. Запуск утилит ImageMagick через командную строку

Более простым и надежным решением является запуск консольных утилит ImageMagick напрямую из 1С без использования COM-компоненты.

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

Чтобы символ конвейера | и кавычки отрабатывали корректно, следует передавать команду через cmd.exe /c:


КомандаЗапуска = "cmd.exe /c ""C:\Program Files\ImageMagick-7.0.7-Q16\magick.exe"" size 400x200 -font Arial -pointsize 20 xc:none -fill grey -gravity NorthWest -draw ""text 10,10 'СтрокаРаз'"" -gravity SouthEast -draw ""text 5,15 'СтрокаДва'"" miff:- | ""C:\Program Files\ImageMagick-7.0.7-Q16\magick.exe"" composite -tile - d1.jpg wmark_text_tiled.jpg";

ЗапуститьПриложение(КомандаЗапуска, , Истина);

Способ 3. Получение ошибок и результатов выполнения через WScript.Shell

Если при выполнении консольных команд необходимо получать текст ошибок (стандартный поток ошибок StdErr) и результат выполнения (поток StdOut), рекомендуется использовать системный объект WScript.Shell вместо ЗапуститьПриложение().

Рассмотрим пример кода:


Шелл = Новый COMОбъект("WScript.Shell");
Команда = "cmd.exe /c magick -density 100 ""C:\temp\pf.pdf"" ""C:\temp\pf.png""";

Процесс = Шелл.Exec(Команда);

// Ожидаем завершения работы команды
Пока Процесс.Status = 0 Цикл
    ОбработкаПрерыванияПользователя();
КонецЦикла;

ТекстОшибки = Процесс.StdErr.ReadAll();
ТекстВывода = Процесс.StdOut.ReadAll();

Если Не ЗначениеЗаполнено(ТекстОшибки) Тогда
    Сообщить("Конвертация успешно завершена!");
Иначе
    Сообщить("Ошибка при выполнении: " + ТекстОшибки);
КонецЕсли;

Итог: Использование консольных команд ImageMagick (особенно для версии ImageMagick 7+) через cmd.exe /c или WScript.Shell избавляет от проблем с разрядностью DLL и зависимостями от устаревших COM-компонентов.

← На главную