Снова КОМПАС преподносит сюрпризы

Автор Lemieux, 27.04.25, 07:16:54

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Lemieux

Доброе утро, коллеги.
Кто-то пытался получить количество запущенных экземпляров КОМПАС для выбора нужного и подключения к нему?
Потому что я попытался и оказалось, что при любом количестве экземпляров из ROT выводит один. Со всеми программами прокатывает, только КОМПАС корявый.

UU

Чтобы получить конкретный экземпляр, его сначала нужно сделать активным, а затем получить интерфейс.
Kompas:=KompasObject(GetActiveOleObject('Kompas.Application.5'));
PS. Как будет работать не проверял, но думаю должно работать.

Lemieux

Цитата: UU от 27.04.25, 07:52:42Как будет работать не проверял, но думаю должно работать.
Не читал, но осуждаю  :laugh:

Кстати, и этот способ не работает. Хотя по задумке, пользователь сначала должен запускать команду из окна, а уже потом выбирать активный инстанс, а не наоборот. А то получается, что контекст у пользователя 2 раза переключается, а не один.

Vi2

Цитата: Lemieux от 27.04.25, 07:16:54Кто-то пытался получить количество запущенных экземпляров КОМПАС для выбора нужного и подключения к нему?
Потому что я попытался и оказалось, что при любом количестве экземпляров из ROT выводит один. Со всеми программами прокатывает, только КОМПАС корявый.
И что там прокатывает с другими приложениями? Это особенность работы ROT (RunningObjectTable, сокращённо ROT, - список активных объектов) и не зависит от приложений, которые регистрируют свои активные объекты. Функция ROT регистрации активного объекта возвращает два кода: S_OK - успешно и MK_S_MONIKERALREADYREGISTERED - успешно, но под таким именем уже зарегистрирован другой объект. Это позволяет приложению фиксировать свою единственность. Однако кто-то игнорирует коды возврата и регистрирует несколько активных объектов (визуально это несколько приложений), кто-то сбрасывает последующие регистрации, но всё равно запускает копии приложения. Вот таким последним является Компас.

В любом случае вторые и последующие регистрации активных объектов не дают возможности получить интерфейс этих копий приложений. При завершении первого приложения становится доступным вторая копия. Но вот для Компаса завершение первого приложения не даёт доступ к другим вообще, потому что в ROT не остаётся активных объектов Компаса.

Цитата: UU от 27.04.25, 07:52:42Чтобы получить конкретный экземпляр, его сначала нужно сделать активным, а затем получить интерфейс.
Kompas:=KompasObject(GetActiveOleObject('Kompas.Application.5'));
PS. Как будет работать не проверял, но думаю должно работать.
Активным - это кликнуть на документ? Это не поможет в силу работы ROT. Но я проверил, нет Компас ничего не делает, чтобы эта копия приложения стало доступным - возвращается самый первый.

GetActiveOleObject - это просто паскалевский вариант запроса к ROT. Он не делает активным объект, как ожидается от названия функции.

UU

Цитата: Lemieux от 27.04.25, 08:22:47Не читал, но осуждаю  :laugh:
Посчитать поголовье не проблема, можно и к конкретным экземплярам подключиться, но пока мне данная задача не нужна.

Lemieux

Цитата: Vi2 от 27.04.25, 10:30:58И что там прокатывает с другими приложениями?
Запущено N-е количество SW. Мой метод возвращает N-е количество COM объектов SW.

Lemieux

Цитата: UU от 27.04.25, 16:45:01Посчитать поголовье не проблема, можно и к конкретным экземплярам подключиться, но пока мне данная задача не нужна.
Как? Вы делаете через ROT или решили схалтурить через процессы?

Vi2

#7
Цитата: Lemieux от 27.04.25, 18:36:34Как? Вы делаете через ROT или решили схалтурить через процессы?
Через ROT не получится никак. Даже с SW. Если работаешь с SW через ROT, то покажи часть кода обращения к объекту.

p3452

Можно работать через ID окон Процессов.., но бессмысленно пытаться работать через COM - GUID всегда одинаков!

Lemieux

Цитата: Vi2 от 27.04.25, 19:31:35Через ROT не поучится никак. Даже с SW. Если работаешь с SW через ROT, то покажи часть код обращения к объекту.
Короче балалайка. SW, AutoCAD выдают инстансы сколько запущено, но сам инстанс ссылается на первый запущенный. Стоит закрыть первый запущенный, то его место занимает, который после него запускался. КОМПАС выдаёт всегда один. 

Vi2

Цитата: Lemieux от 27.04.25, 21:20:21Короче балалайка. SW, AutoCAD выдают инстансы сколько запущено, но сам инстанс ссылается на первый запущенный. Стоит закрыть первый запущенный, то его место занимает, который после него запускался. КОМПАС выдаёт всегда один.
Получение активного объекта возвращает один и тот же объект, который зарегистрирован первым в РОТ. Никаких других инстансов (копий) РОТ не даст, хотя и содержит ссылки на них. Можно перебрать все моникеры в РОТ и определить их общее количество, но это ничего не даст - способа обратиться к второму и последующим инстансам(копиям) системой СОМ не предусмотрено, просто потому, что моникер активного объекта одинаков для каждого инстанса(копии) и содержит GUID основного кокласса(приложения IApplication).

Для Компаса ситуация хуже, потому что он регистрирует ТОЛЬКО первый активный объект, и при его завершении, РОТ не содержит ничего о других инстансах(копиях). И поэтому возвращает Отсутствие объекта.

Дело в том, что активный объект регистрируется в РОТ как моникер элемента в виде "!6B0B5194-4ACD-4095-9BC1-11179FBBB05A" для Компаса. Это один и тот же GUID для любого запущенного Компаса. И возвращает этот моникер из РОТ он один и тот же объект - первый встретившийся. Очевидно, что никаких дополнительных параметров номера инстанса(копии) не предусмотрено.
    [
      uuid(6B0B5194-4ACD-4095-9BC1-11179FBBB05A),
      helpstring("Интерфейс приложения КОМПАС 3D.")
    ]
    coclass Application {
        [default] dispinterface KompasObject;
        [default, source] dispinterface ksKompasObjectNotify;
    };
+ Благодарностей: 1

Student2025

Этот вопрос рассматривался в Бирже прикладных разработок https://forum.ascon.ru/index.php?board=27.0

UU

Цитата: Student2025 от 28.04.25, 06:42:29Этот вопрос рассматривался в Бирже прикладных разработок https://forum.ascon.ru/index.php?board=27.0
А конкретнее.

Student2025


UU


Student2025

А что мешает добавить висящий обработчик или же просто написать простой лаунчер и положить в папку с программой который будет запускать Компас с уникальным ключом  с /Embedding и регистрировать в ROT ?

Кстати давно хотел спросить почему Компас работает с портом ? значит к нему есть доступ через порт ?

Есть еще хакерский трюк по замене объектов в GetRunningObjectTable.

Student2025

Через лаунчер все работает..

KompasApp1 = GetObject("Kompas.Application.7.Tru_lya_lya_my_vezem_s_soboy_kota")

А так было бы удобно если Компас сам бы нумеровал экземпляры в GetRunningObjectTable .
"Kompas.Application.7.1"
"Kompas.Application.7.2"
"Kompas.Application.7.3"
"Kompas.Application.7.4"


Lemieux

Цитата: Vi2 от 27.04.25, 23:42:33Для Компаса ситуация хуже, потому что он регистрирует ТОЛЬКО первый активный объект, и при его завершении
Вот про это я и написал в начале темы, увидев отличное от других программ поведение.

Student2025

Цитата: Lemieux от 28.04.25, 08:13:22Вот про это я и написал в начале темы, увидев отличное от других программ поведение.

Один сказал - не нравится ? что мешает изменить ее конструкцию ? Кто был этот дружок ?

Lemieux

Цитата: Student2025 от 28.04.25, 08:18:17Один сказал - не нравится ? что мешает изменить ее конструкцию ? Кто был этот дружок ?
Изменяйте. Кто Вам мешает? Дружок?