I'm trying to run a Lisp program by calling it from VB Dot Net.
Just for testing, my Lisp code is as follows...
(defun c:DoIt(textb) (setq pntA (getpoint "\nPick A") pntB (getpoint pntA "\nPick B") ) (setq curdoc (vla-get-activedocument (vlax-get-acad-object))) (setq mspace (vla-get-modelspace curdoc)) (vla-addline mspace (vlax-3d-point pntA) (vlax-3d-point pntB)) ; Vlisp works (vla-addText mspace (car textb) (vlax-3d-point (list 0 0 0)) 3.0) ; command line does not work, returns "invalid AutoCAD command:" (command "text" "c" (list 0 0 0) 3.0 0.0 textb) )
And my VB Dot Net code is...
ublic Class MyPlugin <CommandMethod("runlisp", CommandFlags.Session)> _ Public Sub runlisp() Dim commandargs As New ResultBuffer() commandargs.Add(New Autodesk.AutoCAD.DatabaseServices.TypedValue(LispDataType.Text, "c:doit")) commandargs.Add(New Autodesk.AutoCAD.DatabaseServices.TypedValue(LispDataType.Text, "ceil")) 'commandargs.Add(New Autodesk.AutoCAD.DatabaseServices.TypedValue(LispDataType.ListBegin, -1)) 'commandargs.Add(New Autodesk.AutoCAD.DatabaseServices.TypedValue(LispDataType.Text, "ceil")) 'commandargs.Add(New Autodesk.AutoCAD.DatabaseServices.TypedValue(LispDataType.ListEnd, -1)) Dim m_ResultBuf As IntPtr = IntPtr.Zero Dim m_Return As Integer = acedInvoke(commandargs.UnmanagedObject, m_ResultBuf) commandargs.Dispose() If m_Return <> 5100 Then MsgBox(String.Format("Return value {0}", m_Return)) End If End Sub <DllImport("acad.exe", CallingConvention:=CallingConvention.Cdecl, EntryPoint:="acedInvoke")> _ Private Shared Function acedInvoke(ByVal args As IntPtr, ByRef result As IntPtr) As Integer End Function End Class
As I've noted in the Lisp code, the Visual Lisp code to add text is working but the command line version does not, it returns "invalid AutoCAD command:".
Am I doing something wrong or does "command" not work when the lisp is called from dot net?
To call LISP functions via acedInvoke, they must be registered using (vl-acad-defun)
http://forums.autodesk.com/t5/NET/loading-a-lisp-with-dot-net-wizard/m-p/3083852#M24238
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Oops! I see that you use command attribute CommandFlags.Session
(command ...) as far as acedCommand() and acedCmd() can not been called from Application context.
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Thank you for the replies.
So is there NO way to use "command" in a Lisp function that is called from Dot Net?
Or do I have something wrong?
@jshimkus wrote:
So is there NO way to use "command" in a Lisp function that is called from Dot Net?
Or do I have something wrong?
Change CommandFlags.Session with CommandFlags.Modal in your's VB.NET code and try again.
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Thanks, that works for my simple example that I posted.
But what I am really trying to do is this.
I have a command method that opens and closes multiple drawings (has to be "Session" right?), when certain drawings are open I want to run a Lisp program in them, and that Lisp program contains "command" functions.
So while the Session command method is running can I call a Modal command method?
IMHO. You can make two .NET command. One with Session flag, other with Modal flag.
First command open/close dwg-file and start (with Document.SendStringToExecute method, or IAcadDocument.SendCommand method) second command, which call Lisp.
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Thanks! You've been a big help, I will give that a try.
One last question, can both of the command methods be in the same class?
CommCorp wrote:
[...]One last question, can both of the command methods be in the same class?[...]
Yes.
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Sorry to bother you again but I have attempted to implement your suggestions but it still is not quite working for me.
Close, but not quite. The program is opening the new drawing, and I can tell that it tries to execute the Lisp program because the command line says "Command: runlisp", but then it errors out with a "Fatal Error unhandled access violation". I cant' use "sendstringtoexecute" as you suggested because that does not run until the DotNet program has finished and at that point the drawings ive created are long closed.
Attached is an abbreviated, but more acurate, code structure to show exactly what im trying to do.
Do you see what I am doing wrong?
Public Class DwgGenerator <CommandMethod("DwgGen", CommandFlags.Session)> _ Public Sub Get_Data() ' figure which drawing to create and create it Create_constdwg(ConstFolder, DWGName, ConstLevel, progType, progFile, progCmnd, progExec) End Sub Public Sub Create_constdwg(ByVal ConstFolder As String, ByVal DWGName As String, ByVal ConstLevel As String, _ ByVal progType As String, ByVal progFile As String, ByVal progCmnd As String, ByVal progExec As String) ' create the new drawing, open and set as active dwg. Then run the Lisp program in it. Try Dim newdoc As Document = myAcadApp.DocumentManager.Add(TemplateDwgFullPath) Using newdoc.LockDocument ' save it to its actual name newdoc.Database.SaveAs(ConstFolder & DWGName & ".dwg", DwgVersion.Current) End Using newdoc.CloseAndDiscard() 'open the newly created construct and set as the active document newdoc = myAcadApp.DocumentManager.Open(ConstFolder & DWGName & ".dwg", False, "") Using newdoc.LockDocument myAcadApp.DocumentManager.MdiActiveDocument = newdoc ' launch the Lisp program. app.ActiveDocument.SendCommand("runlisp" & vbCr) End Using newdoc.CloseAndSave(ConstFolder & DWGName & ".dwg") Catch ex As System.Exception MessageBox.Show(ex.Message, "Construct create Error") End Try End Sub <CommandMethod("runlisp", CommandFlags.Modal)> _ Public Sub runlisp() Dim commandargs As New ResultBuffer() app.ActiveDocument.SendCommand("(load """ & progFile & """)" & vbCr) commandargs.Add(New Autodesk.AutoCAD.DatabaseServices.TypedValue(LispDataType.Text, "c:netdrawshell")) commandargs.Add(New Autodesk.AutoCAD.DatabaseServices.TypedValue(LispDataType.Text, "ceil")) Dim m_ResultBuf As IntPtr = IntPtr.Zero Dim m_Return As Integer = acedInvoke(commandargs.UnmanagedObject, m_ResultBuf) commandargs.Dispose() If m_Return <> 5100 Then MsgBox(String.Format("Return value {0}", m_Return)) End If End Sub <DllImport("acad.exe", CallingConvention:=CallingConvention.Cdecl, EntryPoint:="acedInvoke")> _ Private Shared Function acedInvoke(ByVal args As IntPtr, ByRef result As IntPtr) As Integer End Function End Class