При попытке инициализировать COM-объект ImageMagick из платформы 1С с помощью конструктора Новый COMОбъект("ImageMagickObject.MagickImage.1") разработчики часто сталкиваются с ошибкой -2147221164(0x80040154): Класс не зарегистрирован. При этом аналогичный код в файле VBScript на том же компьютере может выполняться без каких-либо сбоев.
Рассмотрим подробно причины возникновения этой проблемы и разберем практические способы её решения.
Разберем ситуацию, почему один и тот же код работает из VBScript, но выбивает ошибку в 1С:
.vbs запускаются через 64-битный интерпретатор. Если на сервере или рабочей станции установлена 64-битная версия ImageMagick, то 64-битный VBScript легко находит зарегистрированный COM-объект. Однако если клиент 1С является 32-битным (x86), он запускается в подсистеме WOW64. 32-битное приложение 1С не может напрямую загрузить 64-битную внутрипроцессную библиотеку (In-Process DLL ImageMagickObject.dll), из-за чего система выдаёт ошибку 0x80040154.ImageMagickObject.dll признана устаревшей и по умолчанию не всегда регистрируется или поставляется в дистрибутиве.Проверить это поведение можно, запустив ваш тестовый VBScript через 32-битный хост из папки C:\Windows\SysWOW64\wscript.exe. Вы увидите ту же ошибку, что и в 1С.
Если требуется использовать именно COM-объект ImageMagick из 32-битного клиента 1С при установленной 64-битной компоненте, можно настроить вызов библиотеки через суррогатный процесс dllhost.exe в COM+.
Разберем процесс настройки по шагам:
Win + R и введя comexp.msc).ImageMagickCOM) и выберем тип Серверное приложение (Server Application).ImageMagickObject.MagickImage.1.После этой настройки 32-битный процесс 1С сможет обращаться к 64-битному COM-объекту через запущенный суррогатный процесс Windows.
Более простым и надежным решением является запуск консольных утилит 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";
ЗапуститьПриложение(КомандаЗапуска, , Истина);
Если при выполнении консольных команд необходимо получать текст ошибок (стандартный поток ошибок 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-компонентов.