Проблема с совместимостью Photoshop с COM-интерфейсом

#c# #com #photoshop #clsid

#c# #com #photoshop #clsid

Вопрос:

Мы пишем простое приложение .NET C # COM для Photoshop, которое предназначено для запуска во всех версиях от CS2 до CS5 и всех промежуточных. Это же приложение также существует в форме JavaScript и работает со всеми вышеупомянутыми версиями, поскольку мы избегали реализации функциональности, зависящей от версии.

Проблема, с которой мы столкнулись, связана с COM-интерфейсом. Например, если наше приложение скомпилировано с использованием Interop.Библиотека DLL Photoshop из Photoshop CSx не запускается в Photoshop CSy. По-видимому, это связано с тем, что CLSID реестра специфичен для каждой версии Photoshop, из-за чего наше приложение не может найти правильную библиотеку DLL интерфейса COM, если запущено в системе, в которой установлена версия Photoshop, отличная от той, для которой мы скомпилировали (при условии, что оба приложения являются 32-разрядными).

Если это действительно проблема, нам интересно, можно ли было бы повторно зарегистрировать COM-интерфейс Photoshop версии CSx с CSy CLSID, игнорируя тот факт, что функциональность может отличаться в разных версиях.

Более подробная информация приведена ниже:

Наш основной Photoshop.CLSID приложения находится здесь, в реестре: HKEY_CLASSES_ROOT HKEY_CLASSES_ROOTPhotoshop.Application CLSID Этот CLSID должен соответствовать CLSID, для которого было создано наше приложение. Например, этот идентификатор отличается между CS5 и CS5.1.

На сегодняшний день нашим единственным решением является создание определенных версий нашего приложения для определенных версий Photoshop, и это возможно только в том случае, если у нас установлена эта конкретная версия приложения.

Мы получаем код ошибки 0x80040154: «Не удалось восстановить фабрику COM-класса для компонента с CLSID {116EE066-135E-4F63-8D0E-78F62705FBFC}». Это приложение было создано с использованием CS5.1, но запущено на CS5.04, в результате чего COM-интерфейс не был найден. Этот CLSID специфичен для CS5.1. В заключение, нам необходимо повторно зарегистрировать COM-интерфейс в соответствии с CLSID CS5.04, чтобы иметь возможность запускать наше приложение в этой конкретной версии. Возможно ли это или есть другой способ?

Мы чрезвычайно ценим любую помощь или подсказку, которую мы можем получить по этому вопросу.

Комментарии:

1. Есть ли место со всеми COM-объектами, которые поддерживает Photoshop? Я делаю нечто подобное и не могу найти способ создать пользовательский цветовой профиль CMYK с помощью автоматизации.

Ответ №1:

Изменение GUID классов COM и интерфейса является жестким требованием, это позволяет избежать ада DLL. Чтобы вызвать обычную проблему, с которой вы имеете дело прямо сейчас: версия Hell. При попытке использовать версию фрагмента кода, который не установлен на компьютере, вы получаете диагностическое сообщение вместо случайного недиагностируемого сбоя. Вы не можете надежно выполнить повторную регистрацию, что может серьезно испортить компьютер вашего клиента.

Да, вы можете сделать это так, как это делает Javascript: используйте позднюю привязку. Вы не используете библиотеку interop. Это очень болезненно делать на C #, если вы используете версию более раннюю, чем 4, вам придется использовать отражение. Но это легко сделать с VB.NET или с помощью ключевого слова dynamic C # версии 4. В этой статье размером в KB показано позднее связывание в C # старым способом. С помощью ключевого слова dynamic вы можете написать код так, как он написан у вас сейчас, за исключением синтаксиса создания объекта. Любая проблема несоответствия версий все равно вызовет исключение, но только при вызове свойства или метода и только во время выполнения, а не во время компиляции.

Комментарии:

1. Ханс, большое тебе спасибо за твой ответ. Теперь мы переписали наше приложение в соответствии с предложенным динамическим подходом и можем сообщить, что оно работает безупречно. Например, вместо Photoshop.ApplicationClass app = new Photoshop.ApplicationClass(); мы просто объявляем dynamic app = Activator.CreateInstance(Type.GetTypeFromProgID("Photoshop.Application")); . В качестве бонуса, при использовании ключевого слова dynamic мы избегаем чрезмерного приведения типов. Например, вместо (app.ActiveDocument.ActiveLayer as ArtLayer).Name мы просто пишем app.ActiveDocument.ActiveLayer.Name .

2. это действительно полезно. использование dynamic просто решает проблему.