От кнопки Автокада не запускается программа содержащая SendCommand (COM.INTEROP)

Автор Тема: От кнопки Автокада не запускается программа содержащая SendCommand (COM.INTEROP)  (Прочитано 8941 раз)

0 Пользователей и 3 Гостей просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн VnsАвтор темы

  • ADN OPEN
  • Сообщений: 34
  • Карма: 0
AutoCAD 2016 x64
В программе помимо всего прочего выполняется команда Автокада SOLPROF методом SendCommand(поср. COM(INTEROP)). При этом несинхронный SendStringToExecute не годится.
Дело в том, что в режиме отладки программа работает прекрасно. Проблема возникает когда ее запускаешь от кнопки Автокада (макрос кнопки вызывает lisp-файл, а тот уже запускает программу).
При этом происходит исключение - eLockViolation. В программе установлен флаг Session и применяется блокирование документа. Если исключить из списка пространств имен строку
Imports Autodesk.AutoCAD.Interop (и все строки кода, выполняющие команду SOLPROF), то запуск программы от кнопки проходит без проблем.
Как решить эту проблему?
А существует ли в NET.API способ выполнить команду SOLPROF без SendCommand(COM.Interop) и SendStringToExecute ?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А существует ли в NET.API способ выполнить команду SOLPROF без SendCommand(COM.Interop) и SendStringToExecute ?
Есть еще например Editor.Command. http://adn-cis.org/autocad-2015-vyizov-komand.html
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Если в коде используется вызов COM API, то расширение нужно компилировать не как AnyCPU, но под конкретные разрядности: x86 и x64. Ты так делаешь?

Если при работе с COM используется позднее связывание, то можно компилировать как AnyCPU.


Оффлайн VnsАвтор темы

  • ADN OPEN
  • Сообщений: 34
  • Карма: 0
Если в коде используется вызов COM API, то расширение нужно компилировать не как AnyCPU, но под конкретные разрядности: x86 и x64. Ты так делаешь?
Компиляция стояла на AnyCPU, поставил на х64 - результат тот же. А что такое "позднее связывание" ?
Спасибо за ссылки - сейчас займусь просмотром.

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
А что такое "позднее связывание" ?
Когда разрешение связей выполняется в рантайме, а не статически (т.е. не во время компиляции). Ещё можно использовать динамическое программирование (гугл по фразе Dynamic Language Runtime).

Кстати, DLR позволяет на лету использовать IronPython и IronRuby (в т.ч. и в AutoCAD). Это помимо того, что для программирования в AutoCAD можно использовать PowerShell, для тех, кто умеет пользоваться этим инструментом (тынц, тынц). Подробнее можешь почитать в книге, обозначенной под п.3 здесь.

По поводу DLR есть так же такая книга. А по взаимодействию COM и .NET есть хорошая книга "COM and .NET Interoperability", автор ANDREW TROELSEN. PDF-версия книги легко находится в гугле поиском.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Спасибо за ссылки - сейчас займусь просмотром.
Это всё хорошо, но без твоего кода вряд ли мы тебе поможем...
А еще лучше сделай минимальный тестовый проект, в котором демонстрируется твоя ошибка.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн VnsАвтор темы

  • ADN OPEN
  • Сообщений: 34
  • Карма: 0
Андрей, огромное спасибо за ссылки - выберу время - ознакомлюсь. Пока это все для меня - высокие материи.

Здесь пример кода, который (повторюсь) хорошо работает в режиме отладки, но не работает от кнопки

Код - vb.net [Выбрать]
  1. Imports System
  2. Imports Autodesk.AutoCAD.Runtime
  3. Imports Autodesk.AutoCAD.ApplicationServices
  4. Imports Autodesk.AutoCAD.DatabaseServices
  5. Imports Autodesk.AutoCAD.Geometry
  6. Imports Autodesk.AutoCAD.EditorInput
  7. Imports Autodesk.AutoCAD.Interop
  8.  
  9. Namespace Test
  10.     Public Class MyCommands
  11.         <CommandMethod("Test", CommandFlags.Session)> _
  12.         Public Sub MyMain()
  13.             Dim doc As Document = Application.DocumentManager.MdiActiveDocument
  14.             Dim db As Database = doc.Database
  15.             Using myTrans As Transaction = db.TransactionManager.StartTransaction()
  16.                 Using LockDoc As DocumentLock = doc.LockDocument()
  17.                     Dim bt As BlockTable = myTrans.GetObject(db.BlockTableId, OpenMode.ForRead)
  18.                     Dim btr As BlockTableRecord = myTrans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
  19.                     '' создаем Solid3d -клин
  20.                     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  21.                     Dim Wedge As Solid3d = New Solid3d()
  22.                     Wedge.CreateWedge(10, 15, 20)
  23.                     Wedge.ColorIndex = 1
  24.                     btr.AppendEntity(Wedge)
  25.                     myTrans.AddNewlyCreatedDBObject(Wedge, True)
  26.  
  27.                     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  28.                     LayoutManager.Current.CurrentLayout = "Layout1"
  29.                     Dim PVpCenter(0 To 2) As Double, PVpWidth As Double = 200, PVpheight As Double = 150
  30.                     PVpCenter(0) = 142 : PVpCenter(1) = 110
  31.  
  32.                     ' создаем обьект Viewport
  33.                     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  34.                     Dim PSbtr As BlockTableRecord = myTrans.GetObject(bt(BlockTableRecord.PaperSpace), OpenMode.ForWrite)
  35.                     Using PVportObj As Viewport = New Viewport()
  36.                         PVportObj.CenterPoint = New Point3d(PVpCenter) : PVportObj.Width = PVpWidth : PVportObj.Height = PVpheight
  37.                         PSbtr.AppendEntity(PVportObj) : myTrans.AddNewlyCreatedDBObject(PVportObj, True)
  38.                         PVportObj.ViewDirection = New Vector3d(1, -1, 0.5)  ' изменяем направление взгляда
  39.                         PVportObj.On = True
  40.                         doc.Editor.SwitchToModelSpace()
  41.                     End Using
  42.  
  43.                     Call Zoom(pMin:=Wedge.Bounds.Value.MinPoint, pMax:=Wedge.Bounds.Value.MaxPoint, Centr:=New Point3d(), SFactor:=4) 'зуммируем клин
  44.  
  45.                     Dim res As PromptSelectionResult = doc.Editor.SelectAll ' выбираем все
  46.  
  47.                     ' выполняем команду solprof
  48.                     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  49.                     Dim App As AcadApplication = Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication
  50.                     Dim myDoc As AcadDocument = App.ActiveDocument
  51.                     myDoc.SendCommand("_solprof" & vbCr & "Previous" & vbCr & vbCr & "Y" & vbCr & "Y" & vbCr & "N" & vbCr)
  52.                     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  53.  
  54.                     res = doc.Editor.SelectAll ' опять выбираем все
  55.  
  56.                     Dim n As Integer = 0, blockObj1 As BlockReference = Nothing, blockObj2 As BlockReference = Nothing
  57.                     For Each id As ObjectId In res.Value.GetObjectIds()                  'определяем блоки на слоях PV и PH
  58.                         Dim ent As Entity = myTrans.GetObject(id, OpenMode.ForWrite, True)
  59.                         If Left(ent.Layer, 2) = "PV" Then blockObj1 = ent 'блок видимых линий
  60.                         If Left(ent.Layer, 2) = "PH" Then blockObj2 = ent : n = 1 'блок невидимых линий
  61.                     Next id
  62.  
  63.                     'удаляем блок невидимых линий
  64.                     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  65.                     If n <> 0 Then blockObj2.Erase()
  66.                     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  67.                     ' уводим клин в сторону
  68.                     Wedge.TransformBy(Matrix3d.Displacement(New Point3d(0, 0, 0).GetVectorTo(New Point3d(30, 0, 0))))
  69.  
  70.                 End Using
  71.                 myTrans.Commit()
  72.             End Using
  73.         End Sub
  74.  
  75.         Public Sub Zoom(ByVal pMin As Point3d, ByVal pMax As Point3d, ByVal Centr As Point3d, ByVal SFactor As Double)
  76.             Dim doc As Document = Application.DocumentManager.MdiActiveDocument
  77.             Dim Db As Database = doc.Database
  78.             Using acTrans As Transaction = Db.TransactionManager.StartTransaction()
  79.                 Using myView As ViewTableRecord = doc.Editor.GetCurrentView()
  80.                     Dim dWidth As Double, dHeight As Double, CentPt As Point2d
  81.                     dWidth = pMax.X - pMin.X
  82.                     dHeight = pMax.Y - pMin.Y
  83.                     CentPt = New Point2d(((pMax.X + pMin.X) / 2), ((pMax.Y + pMin.Y) / 2))
  84.                     myView.Height = dHeight * SFactor : myView.Width = dWidth * SFactor
  85.                     myView.CenterPoint = CentPt
  86.                     doc.Editor.SetCurrentView(myView)
  87.                 End Using
  88.                 acTrans.Commit()
  89.             End Using
  90.         End Sub
  91.     End Class
  92. End Namespace


Александр, мне очень понравился метод Editor.Command(), но он не работает в автоматическом режиме - явно не хватает символов-разделителей, имитирующих Enter.
Например, ту же команду SOLPROF в VBA в автоматическом режиме можно выполнить строкой:
SendCommand("_solprof" & vbCr & "Previous" & vbCr & vbCr & "Y" & vbCr & "Y" & vbCr & "N" & vbCr),
где vbCr равнозначно Enter - после опции Previous - два Enter, т.е. выбор объектов завершен.
В методе doc.Editor.Command("_solprof", "Previous", "Y", "Y", "N") вероятно пробел имитирует Enter, но вставить второй  Enter после Previous я не смог, как ни старался.
А может быть Editor.Command() работает только в шарпе?
Прошу прощения, отформатировать код опять не смог.

« Последнее редактирование: 27-08-2016, 13:58:30 от Александр Ривилис »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Прошу прощения, отформатировать код опять не смог.
Учись!
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
но не работает от кнопки
О какой кнопке идёт речь? Кнопки бывают разные.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Vns 27-08-2016, 15:06:24

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Поместил команду TEST на кнопку в Toolbar. Немного подредактировал код:

Код - vb.net [Выбрать]
  1. Imports System
  2. Imports Autodesk.AutoCAD.Runtime
  3. Imports Autodesk.AutoCAD.ApplicationServices
  4. Imports Autodesk.AutoCAD.DatabaseServices
  5. Imports Autodesk.AutoCAD.Geometry
  6. Imports Autodesk.AutoCAD.EditorInput
  7. Imports Autodesk.AutoCAD.Interop
  8.  
  9. Namespace Test
  10.     Public Class MyCommands
  11.         '<CommandMethod("Test", CommandFlags.Session)> _
  12.         ' Убрал CommandFlags.Session
  13.         <CommandMethod("Test")> _
  14.         Public Sub MyMain()
  15.             Dim doc As Document = Application.DocumentManager.MdiActiveDocument
  16.             Dim db As Database = doc.Database
  17.             Using myTrans As Transaction = db.TransactionManager.StartTransaction()
  18.                 Using LockDoc As DocumentLock = doc.LockDocument()
  19.                     Dim bt As BlockTable = myTrans.GetObject(db.BlockTableId, OpenMode.ForRead)
  20.                     Dim btr As BlockTableRecord = myTrans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
  21.                     '' создаем Solid3d -клин
  22.                     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  23.                     Dim Wedge As Solid3d = New Solid3d()
  24.                     Wedge.CreateWedge(10, 15, 20)
  25.                     Wedge.ColorIndex = 1
  26.                     btr.AppendEntity(Wedge)
  27.                     myTrans.AddNewlyCreatedDBObject(Wedge, True)
  28.  
  29.                     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  30.                     LayoutManager.Current.CurrentLayout = "Layout1"
  31.                     Dim PVpCenter(0 To 2) As Double, PVpWidth As Double = 200, PVpheight As Double = 150
  32.                     PVpCenter(0) = 142 : PVpCenter(1) = 110
  33.  
  34.                     ' создаем обьект Viewport
  35.                     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  36.                     Dim PSbtr As BlockTableRecord = myTrans.GetObject(bt(BlockTableRecord.PaperSpace), OpenMode.ForWrite)
  37.                     Using PVportObj As Viewport = New Viewport()
  38.                         PVportObj.CenterPoint = New Point3d(PVpCenter) : PVportObj.Width = PVpWidth : PVportObj.Height = PVpheight
  39.                         PSbtr.AppendEntity(PVportObj) : myTrans.AddNewlyCreatedDBObject(PVportObj, True)
  40.                         PVportObj.ViewDirection = New Vector3d(1, -1, 0.5)  ' изменяем направление взгляда
  41.                         PVportObj.On = True
  42.                         doc.Editor.SwitchToModelSpace()
  43.                     End Using
  44.  
  45.                     Call Zoom(pMin:=Wedge.Bounds.Value.MinPoint, pMax:=Wedge.Bounds.Value.MaxPoint, Centr:=New Point3d(), SFactor:=4) 'зуммируем клин
  46.  
  47.                     Dim res As PromptSelectionResult = doc.Editor.SelectAll ' выбираем все
  48.  
  49.                     ' выполняем команду solprof
  50.                     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  51.                     Dim App As AcadApplication = Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication
  52.                     Dim myDoc As AcadDocument = App.ActiveDocument
  53.                     'myDoc.SendCommand("_solprof" & vbCr & "_Previous" & vbCr & vbCr & "_Y" & vbCr & "_Y" & vbCr & "_N" & vbCr)
  54.                     ' Заменил myDoc.SendCommand на Editor.Command
  55.                     Dim ed As Editor = doc.Editor
  56.                     ed.Command("_solprof", "_Previous", "", "_Y", "_Y", "_N")
  57.  
  58.                     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  59.  
  60.                     res = doc.Editor.SelectAll ' опять выбираем все
  61.  
  62.                     Dim n As Integer = 0, blockObj1 As BlockReference = Nothing, blockObj2 As BlockReference = Nothing
  63.                     For Each id As ObjectId In res.Value.GetObjectIds()                  'определяем блоки на слоях PV и PH
  64.                         Dim ent As Entity = myTrans.GetObject(id, OpenMode.ForWrite, True)
  65.                         If Left(ent.Layer, 2) = "PV" Then blockObj1 = ent 'блок видимых линий
  66.                         If Left(ent.Layer, 2) = "PH" Then blockObj2 = ent : n = 1 'блок невидимых линий
  67.                     Next id
  68.  
  69.                     'удаляем блок невидимых линий
  70.                     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  71.                     If n <> 0 Then blockObj2.Erase()
  72.                     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  73.                     ' уводим клин в сторону
  74.                     Wedge.TransformBy(Matrix3d.Displacement(New Point3d(0, 0, 0).GetVectorTo(New Point3d(30, 0, 0))))
  75.  
  76.                 End Using
  77.                 myTrans.Commit()
  78.             End Using
  79.         End Sub
  80.  
  81.         Public Sub Zoom(ByVal pMin As Point3d, ByVal pMax As Point3d, ByVal Centr As Point3d, ByVal SFactor As Double)
  82.             Dim doc As Document = Application.DocumentManager.MdiActiveDocument
  83.             Dim Db As Database = doc.Database
  84.             Using acTrans As Transaction = Db.TransactionManager.StartTransaction()
  85.                 Using myView As ViewTableRecord = doc.Editor.GetCurrentView()
  86.                     Dim dWidth As Double, dHeight As Double, CentPt As Point2d
  87.                     dWidth = pMax.X - pMin.X
  88.                     dHeight = pMax.Y - pMin.Y
  89.                     CentPt = New Point2d(((pMax.X + pMin.X) / 2), ((pMax.Y + pMin.Y) / 2))
  90.                     myView.Height = dHeight * SFactor : myView.Width = dWidth * SFactor
  91.                     myView.CenterPoint = CentPt
  92.                     doc.Editor.SetCurrentView(myView)
  93.                 End Using
  94.                 acTrans.Commit()
  95.             End Using
  96.         End Sub
  97.     End Class
  98. End Namespace

Вот результат работы:



Что не так? В коде разбираться я не стал, да и что он делает тоже.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн VnsАвтор темы

  • ADN OPEN
  • Сообщений: 34
  • Карма: 0
Ну что сказать? Нет слов! Бесконечно благодарен и совершенно счастлив! Про COM(Interop) теперь можно забыть!