Сообщество программистов Autodesk в СНГ

ADN Club => Civil 3D API => Тема начата: Разживин Алексей от 06-10-2015, 14:19:43

Название: Работа с определенным экземпляром Civil через COM.
Отправлено: Разживин Алексей от 06-10-2015, 14:19:43
Всем привет!
Необходимо через COM-интерфейс из стороннего приложения обратиться к уже открытому Цивилу (или запустить его) и, скажем, нарисовать коготочку.

Ниже приведен код, который это делает. (Написано для 2012 Автокада на основе этого: http://through-the-interface.typepad.com/through_the_interface/2007/12/launching-autoc.html (http://through-the-interface.typepad.com/through_the_interface/2007/12/launching-autoc.html))
Извините, вам запрещён просмотр содержимого спойлеров.


Но при использовании этого метода всплывает пара проблем:
(№1)во первых, если у нас одновременно открыт Автокад, Цивил и Map 3D, то acadApp = Marshal.GetActiveObject("AutoCAD.Application.18.2") присоединится к тому, кто был раньше всех запущен.
А во-вторых (№2), даже если никакого автокада не запущено, то при создании экземпляра приложения через Activator.CreateInstance нет гарантии того, что запустится именно цивил.

Если проявится хоть одна проблема (т.е. мы присоединились НЕ к Цивилу), то на этой строке
Код - C# [Выбрать]
  1. civilApp = acadType.InvokeMember("GetInterfaceObject", BindingFlags.InvokeMethod, null, acadApp, new object[] { "AeccXUiLand.AeccApplication.9.0" });
вылетит TargetInvocationException с ex.InnerException.HResult == -2147467259.

Вопрос: как обратиться к нужному автокаду с цивилом?

Ниже приведены еще пара "черномагических" способов, которые, тем не менее, я не смог заставить работать на себя.

Первый:
Лезем в Running Object Table, выбираем объекты с CLSID Автокада и пытаемся получить из них объекты Цивила. Здесь появляется проблема №1. Даже если записей в ROT несколько, каждая запись является экземпляром первого открытого автокада.
Извините, вам запрещён просмотр содержимого спойлеров.


Второй:
Не знаю, насколько вообще этот способ корректен, делалось по советам отсюда http://stackoverflow.com/questions/770173/how-to-get-excel-instance-or-excel-instance-clsid-using-the-process-id (http://stackoverflow.com/questions/770173/how-to-get-excel-instance-or-excel-instance-clsid-using-the-process-id).
Вкратце: получаем процесс автокада по имени, получаем дескриптор главного окна. С помощью функции AccessibleObjectFromWindow (https://msdn.microsoft.com/en-us/library/windows/desktop/dd317978%28v=vs.85%29.aspx (https://msdn.microsoft.com/en-us/library/windows/desktop/dd317978%28v=vs.85%29.aspx)) получаем объект, указывая полученный дескриптор и CLSID Автокада.
Извините, вам запрещён просмотр содержимого спойлеров.


Просьба не сильно бить ногами, так как я не волшебник, а только учусь :) и могу где-нибудь ошибаться.
В аттаче приложен проект с полными исходниками моих начинаний.
Название: Re: Работа с определенным экземпляром Civil через COM.
Отправлено: Александр Ривилис от 06-10-2015, 15:13:21
Необходимо через COM-интерфейс из стороннего приложения обратиться к уже открытому Цивилу (или запустить его)
Я бы вообще отказался от этой идеи. Логично сделать так:
1) Написать плагин (dll-сборку), которая грузится в Civil 3D и умеет делать то, что нужно
2) Написать внешнее приложение, которое запускает Civil 3D, но не через COM/ActiveX, а через Process.Start (ну или как-то аналогично) и запускает на выполнение нужный плагин из п.1 (например посредством сформированного scr-файла)
Идея с запуском и обращением к AutoCAD/Civil 3D посредством COM/ActiveX не выдерживает критики в силу того, что на каждое обращение к AutoCAD/Civil 3D нужно сделать кучу проверок (см. здесь: http://adn-cis.org/kak-ispolzuya-visual-c-zapustit-autocad-i-zastavit-ego-vyipolnyat-nekotoryie-dejstviya.html)
Так что если есть хотябы минимальная возможность уйти от этого сценария, то я бы рекомендовал это сделать.

Название: Re: Работа с определенным экземпляром Civil через COM.
Отправлено: Кирилл Захаров от 08-11-2018, 12:35:36
Я искал информацию на форуме по слову COM и случайно попал на эту тему.
Мне стало интересно.
Хочу спросить на будущее, вдруг пригодится:
например посредством сформированного scr-файла
Можно ли поподробнее рассказать о том, как это сделать? Что это за scr-файл? Как его можно использовать? Его можно запустить из стороннего приложения?


Название: Re: Работа с определенным экземпляром Civil через COM.
Отправлено: Александр Ривилис от 08-11-2018, 12:41:45
Что это за scr-файл? Как его можно использовать?
Это обычный текстовый файл, содержащий последовательность команд AutoCAD (Civil 3D) и который AutoCAD может выполнять при помощи команды _SCRIPT (http://help.autodesk.com/view/OARX/2018/RUS/?guid=GUID-95BB6824-0700-4019-9672-E6B502659E9E) или через опцию командной строки /b: https://knowledge.autodesk.com/ru/support/autocad/learn-explore/caas/CloudHelp/cloudhelp/2018/RUS/AutoCAD-Core/files/GUID-8E54B6EC-5B52-4F62-B7FC-0D4E1EDF093A-htm.html
Название: Re: Работа с определенным экземпляром Civil через COM.
Отправлено: Дмитрий Загорулькин от 08-11-2018, 13:17:12
А также его можно использовать в утилите ScriptPro (https://knowledge.autodesk.com/support/autocad/downloads/caas/downloads/content/autodesk-customization-conversion-tools.html) для пакетной обработки чертежей.