Возможно взаимодействие с 64-битным COM-сервером (Photoshop) from.NET?


Я пытался написать некоторый код для взаимодействия с Photoshop, как путем добавления ссылки COM, так и путем позднего связывания. Мне потребовалось некоторое время, чтобы понять, что код действительно работает, но не с 64-битной версией Photoshop.

Исключение, которое я получаю с 64-битным Photoshop, выглядит следующим образом:

COMException был необработан

Получение фабрики классов COM для компонента с CLSID {D9389EDE-AEF8-4092-9377-075E94B7CB9A} сбой из-за следующей ошибки: 80080005 сбой выполнения сервера (Исключение из HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).

Возможно ли для моего приложения взаимодействовать с 64-битной версией Photoshop? Или он ограничивается только общением с 32-битной версией?

Я столкнулся с этим в одной из моих многочисленных попыток найти решение, но я не вижу, как я мог бы использовать флаг CLSCTX_ACTIVATE_64_BIT_SERVER либо с COM-ссылкой, либо с поздней привязкой, ну, предположив, что это - это решение.

Исключение происходит здесь:

Type photoshopType = Type.GetTypeFromProgID("Photoshop.Application");
if (photoshopType != null)
{
    object photoshop = Activator.CreateInstance(photoshopType);
5 11

5 ответов:

Исполняемые файлы приложений .NET (.exe) всегда будет выполняться в собственной разрядности запущенной архитектуры процессора, если она помечена для AnyCPU, который компилируется вплоть до MSIL. Таким образом, любая сборка MSIL, работающая на 64-разрядной платформе, будет работать на 64-разрядной, а на 32-разрядной платформе-на 32-разрядной.

В вашем случае вы либо хотите выполнить компиляцию для AnyCPU, но если вы должны принудительно использовать 64-битное взаимодействие, используйте x64. Конечно, на 32-битной машине это не сработает. Это будет изначально считываться из 64-разрядного представления реестр (включая InProc

Вы также должны быть осторожны с тем, как маршалируются указатели. Обязательно используйте IntPtr для дескрипторов при написании собственного прокси-сервера взаимодействия.

Пара вещей, которые нужно проверить для использования COM из / в различных средах:

  1. переключите "Embed Interop Types" для ссылки COM (см. Рисунок 1)
  2. Проверьте целевую платформу (см. рис. 2)

Рисунок 1-Эталонное СвойствоРисунок 2 - Целевая Платформа

Исходя из той небольшой информации, которой мы располагаем:

цитируется из: Когда CoCreateInstance возвращает 0x80080005 (CO_E_SERVER_EXEC_FAILURE)


... Если клиент не удается вызвать CoRegisterClassObject() с того момента, как начался процесс начато, или не удается позвонить CoRegisterClassObjects () вообще для фабрика данного класса, затем клиент получит Ошибка CO_E_SERVER_EXEC_FAILURE в Метод cocreateinstance(...). Такое может случиться для целый ряд причин:

1) машина имеет высокую загрузку процессора и процесс занимает много времени, чтобы начать и выполнить приказ CoRegisterClassObjects() менее чем за 120 секунд.

2) COM-сервер не регистрируется для правильные идентификаторы классов.

3) сервер COM В настоящее время остановка и есть состояние гонки между CoCreateInstance и COM часть остановки сервера.

4) существует проблема безопасности в как работает COM-сервер начать это страница, кажется, предлагает ошибочное написание пароли или отсутствие "Login as Пакетное задание "привилегия для" запуска от имени.." COM-серверы, но в любом случае я бы предложите перепроверить эту информацию для вашей конкретной конфигурации)

Я не очень разбираюсь в API Photoshop, поэтому попытаюсь ответить на ваш вопрос немного более обобщенно.

32-битные приложения не могут загружать 64-битный код в свое адресное пространство и наоборот. Это означает, что единственный способ смешать их - это через некоторую форму межпроцессной коммуникации.

COM будет обрабатывать эту межпроцессную связь для вас, если это сервер com вне процесса. Таким образом, если объекты Photoshop COM реализованы как объекты вне процесса, то все будет хорошо работать. Поскольку это не работает для вас, я предполагаю, что они используют в процессе объекты, которые не могут быть смешаны между 32 и 64 битами. В этом случае вам нужно будет создать свой собственный сервер обработки, который обертывает объекты Photoshop, которые вы хотите использовать. Затем вы можете использовать эту внешнюю оболочку процесса как из 32, так и из 64-битного кода.

Кроме того, чтобы прояснить некоторые другие сообщения, в .NET вам нужно убедиться, что цель платформы установлена на то, что вам нужно для того, что вы пытаетесь выполнять. x86 сделает ваш код всегда работать как 32-битный. x64 сделает его всегда работать как 64-битный. Любой процессор сделает его работать как 32 бит на 32-битной ОС и 64 бит на 64-битной ОС.

Проблема 64/32-битных версий немного сложнее, так как вы можете запускать 32-битный photoshop на 32-битной ОС. Я бы попробовал ради тестирования установить целевой проект на x64, и если это может запустить photoshop64, то вы можете даже сделать так, чтобы ваш код компилировался дважды (2 DLL) и загружался в соответствии с версией photoshop.