2

What I would like to do is have an AutoLISP program call an executable file and get a response from that executable.

I understand that we are currently able to call applications with startapp e.g.

(startapp "notepad.exe" "acad.lsp")

but to my understanding, I don't believe that startapp can return values from the called application.

In context I would like to be able to call an application from lisp and when that application is closing, to send a status code back to the lisp that will allow it to continue execution.

in fake lisp code

(
    (startapp "myapp.exe" "args")
    (*DO UNTIL STATUS CODE == 1* or *"myapp.exe is stopped*
        *CODE*
    )
    *CONTINUE EXECUTION
)

If something of this nature is possible in LISP, or if there is a better way to see if a process has ended in LISP, any direction would be appreciated.

Breeze
  • 2,010
  • 2
  • 32
  • 43
Bigbob556677
  • 1,805
  • 1
  • 13
  • 38
  • 1
    if you can check existence of files, you can use existence of files as flags. you can also have your "external" app output to a file and later read it from that file, in your lisp. – Will Ness Oct 27 '17 at 18:28
  • @WillNess That is a way to do it. And not necessarily a bad one. Ideally, the lisp code would be able to store the process as a variable rather than referencing an external file. Thanks! – Bigbob556677 Oct 27 '17 at 18:32
  • see also: https://stackoverflow.com/questions/8477753/visual-lisp-how-to-call-functions-in-external-c-dll – Will Ness Oct 27 '17 at 18:35
  • Did you read some documentation about your AutoLisp (perhaps [this](http://docs.autodesk.com/ACDMAC/2013/ENU/PDFs/acdmac_2013_autolisp_developers_guide.pdf)). Some Lisp implementations can call foreign functions coded in C or C++. – Basile Starynkevitch Oct 27 '17 at 18:43
  • When I first started with AutoCAD, I gave AutoLisp a try and found it extremely hard to learn and use. I am fully aware that it is extremely powerful for a skilled user, but it is not pleasant getting there. If you have some .NET experience, I think you will find that you can do so much more with their .NET API (not to mention the .NET framework). COM Interop, FileSystemWatcher or Process class will make short work of your problem as per comments above. – Nik Oct 27 '17 at 23:45
  • @Nik You know. I dont actually use AutoDesks Autocad. I use Progecad, which allows for .NET integration but every time I load one of my plugins and run a command it says Non-static method requires a target. – Bigbob556677 Oct 30 '17 at 14:46
  • 1
    @Philip556677, I can't say I am familiar with Progecad, and it might be a stupid question, but have you tried making your command methods static? – Nik Oct 30 '17 at 15:36
  • 1
    @Nik you know. that was my very first idea but vb.net doesnt have a "Static" method so naturally that didnt work. Upon reading your comment i realized that it is called "Shared" in vb.net. Everything works now. lol – Bigbob556677 Oct 30 '17 at 16:01
  • That's great, now you can leave AutoLisp alone and not tear you hair out! – Nik Oct 30 '17 at 16:23

1 Answers1

3

Run the external application and wait until finish process You can do like this:

(command "_Shell" (strcat path app ) )

easy to run, but don't have easy access to returned value.

Or You can do it like this

(defun Sleep (n / lastCmdecho ) 
    (setq lastCmdecho (getvar  "cmdecho"))
    (setvar "cmdecho" 0)
    (eval (list  'VL-CMDF "_.delay" n ) )
    (setvar "cmdecho" lastCmdecho )

)

(defun C:ExternalApplication (  / *error* )
    (defun *error* ( msg / ) 
        (if (not (null msg ) )  (progn (princ "\nC:ExternalApplication:*error*: " ) (princ msg ) (princ "\n")   ) )
    )
    (setq path "C:\\Windows\\")
    (setq app (strcat "Notepad.exe" ) )
    (print (strcat "Run " (strcat path app ) ) )

    (setq Shell (vlax-get-or-create-object "Wscript.Shell"))
    (setq AppHandle(vlax-invoke-method Shell 'Exec (strcat path app ) ))
    (while ( = (vlax-get-property AppHandle 'Status ) 0)
        (Sleep 1000)
    )`
    (vlax-release-object Shell) 
    (print "Process finished" )
)

Now if Your application returns Status, You have it.

If Your application manipulates Acad environment You can set value by system variable (setvar) or environment variable (setenv).

If not, You can save value to system registry and read it for example by: (getcfg )

CAD Developer
  • 1,532
  • 2
  • 21
  • 27