Реклама i
Стань нашим партнером - зарабатывай с нами!
| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > Вызов был отклонен. Внешнее .NET приложение.

Вызов был отклонен. Внешнее .NET приложение.

Ответ
Поиск в этой теме
Непрочитано 05.04.2012, 00:28 #1
Вызов был отклонен. Внешнее .NET приложение.
Дмитрий Асташев
 
päällikön suunnittelijat
 
Pietari, Venäjä
Регистрация: 04.12.2010
Сообщений: 63

Коллеги, доброе время суток!
Есть приложение, написанное на .NET и выполняющееся как внешний exe.
Если во время обращения к API AutoCAD пользователь начинает щелкать мышкой, или выполнять другие непотребства,
то происходит исключение типа System.Runtime.InteropServices.COMException с сообщением:
Вызов был отклонен. (Исключение из HRESULT: 0x80010001 (RPC_E_CALL_REJECTED))

Как запретить (внутри это же программы) пользовательский ввод перед началом обращения к API?
Просмотров: 9122
 
Непрочитано 05.04.2012, 00:54
#2
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,405
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от Дмитрий Асташев Посмотреть сообщение
Как запретить (внутри это же программы) пользовательский ввод перед началом обращения к API?
Ну из внешнего приложения это не запретишь. А зачем? Может быть обрабатывать это исключение? Скажет задержку на сколько-то миллисекунд и повторить действие.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 05.04.2012, 01:09
#3
Дмитрий Асташев

päällikön suunnittelijat
 
Регистрация: 04.12.2010
Pietari, Venäjä
Сообщений: 63


Цитата:
Сообщение от Александр Ривилис Посмотреть сообщение
задержку на сколько-то миллисекунд и повторить действие.
Приложение читает данные из AutoCAD и производит манипуляции со своей базой SQL.
А также читает из SQL и делает разные манипуляции на чертеже.
А предсказать, когда именно пользователь что-то не так сделает, невозможно.
Поэтому желательно выполнить функцию с одной попытки.
Может даже попробовать что-то типа Application.Visible= False, на худой конец.
Или минимизировать окно AutoCAD.
Но где то же должны быть средства, ограничивающие пользовательский ввод?
Дмитрий Асташев вне форума  
 
Непрочитано 05.04.2012, 01:40
#4
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


Если программа должна обращаться в произвольный момент, то блокировка действий пользователя не помжет - т.к. в автокаде могут уже выполняться какие-либо действия. ИХМО - только синхронизирование с автокадом (например запускать, на каких-либо реакторах или напрямую). Второй вариант, практически к любой БД есть COM интерфейс - то есть вся работа с ней может быть выполненна непосредственно из автокада. Я бы, при необходимости во внешней программе, рассмотрел вариант, "помечания" ей соответствующих записей в БД, и паральную обработку этих-же данных непосредственно из Автокада (благо к СУБД паральльное обращение это норма).
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 05.04.2012, 01:43
#5
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,405
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от Дмитрий Асташев Посмотреть сообщение
Но где то же должны быть средства, ограничивающие пользовательский ввод?
Это возможно, но не из внешнего приложения.
Попробуй проверять состояние AcadApplication перед любым обращением к AutoCAD при помощи метода AcadApplication.GetAcadState.IsQuiescent. Что-нибудь типа:
Код:
[Выделить все]
 
while (!acadApp.GetAcadState().IsQuiescent) Thread.Sleep(100);
// Здесь уже можно попытаться обратиться к AutoCAD

Последний раз редактировалось Александр Ривилис, 05.04.2012 в 01:54.
Александр Ривилис вне форума  
 
Непрочитано 05.04.2012, 07:28
#6
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,381


Дима_ правильно советует -
Цитата:
Второй вариант, практически к любой БД есть COM интерфейс - то есть вся работа с ней может быть выполненна непосредственно из автокада.
Если надо "манипуляции на чертеже чертеже" или "данные из AutoCAD в SQL" - это надо делать изнутри AutoCAD. А в NET-приложении - всё прочее, например визуальную работу с данными.

Отклонение вызова возможно по множеству причин, и не только потому, что пользователь "щелкает". Он мог вообще включить режим панорамирования и уйти. Предугадать все варианты невозможно. Ограничить действия пользователя невозможно.

Ну, и конечно, любое обращение к Автокаду надо обертывать в обработчик исключений.
ShaggyDoc вне форума  
 
Непрочитано 05.04.2012, 12:20
#7
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


если есть код внешнего прложения, то лучше его пересобрать как .нет-сборку
gomer вне форума  
 
Непрочитано 05.04.2012, 15:12
#8
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


Цитата:
Сообщение от gomer Посмотреть сообщение
если есть код внешнего прложения, то лучше его пересобрать как .нет-сборку
Зачем COM программу пересобирать как Acad .Net сбокру - кроме дополнительного гемора это ничего не даст??
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 05.04.2012, 16:37
#9
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


по моему обновять чертежы через базу sql это не меньший гемор
gomer вне форума  
 
Непрочитано 05.04.2012, 18:21
#10
Salt

Josser
 
Регистрация: 09.11.2011
Сообщений: 66


Читайте внимательнее, коллеги:
Цитата:
Есть приложение, написанное на .NET и выполняющееся как внешний exe.
Посему, самое разумное - это написать dll на .NET, грузить её в автокад через NETLOAD, а к базе данных обращаться из неё через ADO.NET. И забыть про COM
Salt вне форума  
 
Непрочитано 05.04.2012, 20:49
#11
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


To Salt:
Цитата:
Сообщение от Дмитрий Асташев Посмотреть сообщение
System.Runtime.InteropServices.COMException
Если не "шарите" в технологиях, не путайте людей, внешний exe на .Net он или нет, может общаться с автокадом ТОЛЬКО посредством COM, так что чтоб сделать "реальную" .Net сборку ее надо полностю переписывать используя совершенно другие "методы", технологии и библиотеки. Заворачивать, то что есть, в NetLoad dll и работать изнутри посредством COM - так тоже конечно можно, но это все равно что вилкой суп есть.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 05.04.2012, 21:21
#12
Salt

Josser
 
Регистрация: 09.11.2011
Сообщений: 66


Работа с автокадом из .NET идет через сборки Autodesk.AutoCAD.Interop.dll и Autodesk.AutoCAD.Interop.Common.dll не зависимо от того, из экзешника это делается или из inproc-dll. Таким образом перейдя от .exe к .dll переписывать ничего не придется. Зато появляется возможность создать собственные команды в автокаде и управлять всем процессом из автокада, т.е. надежно и безопасно делать "манипуляции на чертеже" или перегонять "данные из AutoCAD в SQL" (ShaggyDoc).
Ну, а в идеале, писать dll на AutoCAD.NET API, и... забыть про COM

p.s.
http://through-the-interface.typepad.../02/index.html

Последний раз редактировалось Salt, 05.04.2012 в 21:27.
Salt вне форума  
 
Непрочитано 05.04.2012, 21:51
#13
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


Цитата:
Сообщение от Salt Посмотреть сообщение
Зато появляется возможность создать собственные команды в автокаде и управлять всем процессом из автокада, т.е. надежно и безопасно делать "манипуляции на чертеже"
Чтобы создавать команды надо подключить еще "настоящие" акад нет библиотеки, а не переписывая код, ни надежности, ни безопасности не прибавиться - не важно откуда мы их вызовем - библиотеки одни и те-же.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 05.04.2012, 22:02
#14
Salt

Josser
 
Регистрация: 09.11.2011
Сообщений: 66


Цитата:
не важно откуда мы их вызовем
Как раз таки важно! Вызывая из автокада можно блокировать любые другие действия (элементарное модальное диалоговое окно не позволит вам ничего другого делать, пока вы его не закроете).
А из "настоящих"(с) AutoCAD.NET библиотек добавить потребуется совсем немного.
Salt вне форума  
 
Автор темы   Непрочитано 05.04.2012, 23:50
#15
Дмитрий Асташев

päällikön suunnittelijat
 
Регистрация: 04.12.2010
Pietari, Venäjä
Сообщений: 63


Коллеги, благодарю всех за помощь.
Вопрос обсуждался ранее в ветке http://www.caduser.ru/forum/index.ph...D=49&TID=41682
Там был сделан вывод, что придется вынуждено использовать acadApp.Visible = false;
Вопрос, придется или не придется переписывать приложение при переходе от COM программы к ACAD .NET классу?
Я думаю, что придется переписывать практически весь механизм обращения к AutoCAD, ведь разница в подходе очевидна:
например, вставка блока

;;;COM
Dim block As AcadBlockReference
block = mspace.InsertBlock(InsertionPoint, NewBlockName, 1, 1, 1, 0)

;;;ACAD .NET DLL
Dim trans As Transaction = dwg.TransactionManager.StartTransaction
Dim blockRef As BlockReference = New BlockReference(blockRefPointResult.Value, newBlockDef.ObjectId)
Dim curSpace As BlockTableRecord = trans.GetObject(dwg.CurrentSpaceId, OpenMode.ForWrite)
curSpace.AppendEntity(blockRef)
trans.AddNewlyCreatedDBObject(blockRef, True)
trans.Commit()

Пожалуйста, если я не так понимаю, поправьте меня.
Дмитрий Асташев вне форума  
 
Непрочитано 06.04.2012, 00:27
#16
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


Понимаете Вы правильно, но частично, Salt предлагает использовать внутри модуля ACAD .Net dll - COM обращение, что по моему глупо - т.к. проблемы все те-же, его надо как-то вызвать, а делая это снаружи - сталкиваемся ровно с теми же проблемами (и отключение видимости окна, Вам 100% гарантий незанятности автокада не даст). Нельзя к акаду делать реальное паралельное обращение - НИКАК и все тут.
Я повторюсь, делите обязаности, если БД все равно используеться - это очень хороший, удобный и надежный "перевалочный пункт" - не поддерживает паралельную работу ни COM модель, ни .NET API автокада. Нельзя "снаружи" к нему в произвольное время обратиться (либо вылетит, либо "вечно" ждать будете, когда там орбиту выключат). "Повестесь" на соответствующие события и обновляйте по ним базу - если ничего не происходит - в базе же все равно будут "последние" данные, чего-то начал делать (автокад) - вначале сверил актуальность в БД.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Непрочитано 06.04.2012, 00:49
#17
Дмитрий Асташев

päällikön suunnittelijat
 
Регистрация: 04.12.2010
Pietari, Venäjä
Сообщений: 63


Цитата:
Сообщение от Дима_ Посмотреть сообщение
"Повестесь" на соответствующие события и обновляйте по ним базу - если ничего не происходит - в базе же все равно будут "последние" данные, чего-то начал делать (автокад) - вначале сверил актуальность в БД.
Остальное все понял в Вашем сообщении. По выделенному, если не затруднит сильно, можно ли попросить поподробнее оббьяснить, пожалуйста.
Дмитрий Асташев вне форума  
 
Непрочитано 06.04.2012, 01:10
#18
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


Вы обращаетесь к автокаду через объекнтую модель - установите обработчики событий (Events, делегат, реактор...) на нужные Вам (допустим изменился примитив - вы об этом в СУБД сообщили, а заодно проверили, что БД там изменила), если на все примитивы пометки делать "тяжело", продумайте БД таким образом, что-бы она оставляла в специально отведенных записях, о нужной информации, а автокад их соответствующим образом заполнял и если нужно сигнализировал об этом (кстати некоторые СУБД поддерживают функцию "подписки" на обновление информации "в запросе" - то есть если Ваш select ... уже другое выдаст - Вам "звоночек" - то есть сигнализацию о изменении автокадам можно получить "автоматом").
__________________
Когда в руках молоток все вокруг кажется гвоздями.

Последний раз редактировалось Дима_, 06.04.2012 в 01:51.
Дима_ вне форума  
 
Автор темы   Непрочитано 06.04.2012, 12:10
#19
Дмитрий Асташев

päällikön suunnittelijat
 
Регистрация: 04.12.2010
Pietari, Venäjä
Сообщений: 63


To Дима_

Спасибо, теперь понятно. Подход, который Вы предлагаете, безусловно, правильный.
Жаль, что он требует полного переписывания всей программы и поэтому в данном случае неприменим.

Также понял, что корень проблемы кроется в принципиальном отсутствии в AutoCAD механизма параллельного обращения.
в ветке http://www.caduser.ru/forum/index.ph...D=49&TID=41682
Гость Shavt, правда, пишет:
"неуправляемое приложение работает параллельно даже в том случае если пользователь работает с AutoCAD..Net приложение без проверки IAcadApplication.GetAcadState().IsQuiescent сразу же генерирует исключение"
К сожалению, проверить это невозможно.

В случае использования COM, как я понял:

при чтении данных из AutoCAD достаточно делать проверку на состояние AutoCAD В НАЧАЛЕ ЦИКЛА и, в случае его занятости, выводит сообщение и повторять запрос.
при необходимости внесения изменений в чертеж правильно будет вынести необходимые функции в AutoCAD .NET DLL и вызывать их, например, через SendCommand, потому, что проверять на состояние AutoCAD при КАЖДОМ обращении к AutoCAD ВНУТРИ ЦИКЛА будет очень громоздко.
Дмитрий Асташев вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > Вызов был отклонен. Внешнее .NET приложение.

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Обсуждение фильмов Perezz!! Разное 9560 вчера 00:25
ЛИРА-КМ - вызов был отклонен! Alexmf Лира / Лира-САПР 1 07.06.2011 10:30
AutoCAD 2011 при копировании не вставляет в другой чертеж Maxxwell AutoCAD 7 07.05.2010 14:44
Бред Сивой кобылы. БСК - 2008 Admin Разное 468 01.01.2009 19:49
внешнее приложение не работает... Visla AutoCAD 1 05.02.2004 17:33