Author Topic: Has anyone tried to attach to a .net library from outside of autocad to control?  (Read 796 times)

0 Members and 1 Guest are viewing this topic.

Zeftax

  • Newt
  • Posts: 24
  • Measure once, cut thrice, glue, and cut again.
I have some custom commands that I allow users to execute added from a dll. Now, I want to be able to open a drawing and execute a command in it from an external process, has anyone tried that? 
From my research it would seem that the bast way to do it would be to implement IExtensionApplication and in Initialize() start listening to a web socket, to which the external "client" would then send communication, but that seems like an extremely roundabout way of going about it.
I use Central European Time, dunno why my profile says otherwise.
Pastafarian minister, dungeon master, concertina player, and sometimes I do a bit of CADing as well.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8928
  • AKA Daniel
People use ActiveX automation. Have a DLL that auto-loads your commands, then send string to execute

A socket sounds interesting, but I’d bet that’s against the EULA..
Something like.. pseudo code

Code - Python: [Select]
  1. from pyrx_imp import Rx, Ge, Gi, Db, Ap, Ed
  2. import traceback
  3. import socket
  4.  
  5. sock = None
  6.  
  7. def OnPyInitApp():
  8.     global sock
  9.     host = "localhost"
  10.     port = 5150
  11.     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  12.     sock.connect((host, port))
  13.     Ap.Application.registerOnIdleWinMsg(packetListener)
  14.  
  15. def OnPyUnloadApp():
  16.     Ap.Application.removeOnIdleWinMsg(packetListener)
  17.    
  18. def commandRunnerfunc(args = None):
  19.     pass
  20.    
  21. def packetListener():
  22.     try:
  23.         while True:
  24.             data = sock.recv(1024)
  25.             if len(data) > 0:
  26.                 Ap.DocManager.beginExecuteInCommandContext(commandRunnerfunc,data)
  27.             break
  28.     except Exception as err:
  29.         traceback.print_exception(err)
  30.        
  31.  

Zeftax

  • Newt
  • Posts: 24
  • Measure once, cut thrice, glue, and cut again.
Thanks! I will look into that. I have also found from some searching that freecad can be run in console mode or even used as a python library (https://wiki.freecad.org/Embedding_FreeCAD)! Really cool stuff. Unfortunately it does not have autocad-compatible .net interface (or any .net interface at all), but it definitely might be useful in some future project.
I use Central European Time, dunno why my profile says otherwise.
Pastafarian minister, dungeon master, concertina player, and sometimes I do a bit of CADing as well.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8928
  • AKA Daniel

I did not mean use python, it was meant as pseudo code, or an idea outline

.NET has all the above from an AutoCAD API perspective, I.e. Initialize, OnIdle, ExecuteInCommandContext.
You just need to configure the socket

Zeftax

  • Newt
  • Posts: 24
  • Measure once, cut thrice, glue, and cut again.
I understand, the freecad link was just a curiosity I found while searching for a solution. I have been reading their documentation and it looks like a really good piece of software.
I use Central European Time, dunno why my profile says otherwise.
Pastafarian minister, dungeon master, concertina player, and sometimes I do a bit of CADing as well.

MickD

  • King Gator
  • Posts: 3685
  • (x-in)->[process]->(y-out) ... simples!
I'm currently using a websocket at the moment to talk to my web ui.
Yes, it is a bit of a work around but all of my logic/processing is done in my external app, most of the 'smart' data I need is stored externally in a db so I only need cad for graphical representation and to pick points and entities etc (basic user interaction stuff). The reason is I want the user to be able to use the data for whatever they need without being tied to cad all the time.

The work around is mainly in building the api for user interaction but it's really basic, just things like 'pick point' etc then I pass the point through the socket to my app for processing via json.
I can send commands back the same way, this requires you set up some kind of protocol for packing/unpacking data and commands.
The app can run in a web browser or a webview component in a form. It works well :)

...

A socket sounds interesting, but I’d bet that’s against the EULA..
Something like.. pseudo code
...

hmm, I don't see why it would be a problem when most of the COM api is exposed and can be used externally, I guess we'll find out :)

Nice, neat socket code btw :)
I've found I needed to set up a ping event to keep the client socket alive, they will time out after something like 120 seconds, I set one for every 30secs.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Everything that is possible demands to exist"
- Gottfried Wilhelm von Leibniz

n.yuan

  • Bull Frog
  • Posts: 350
You may want to explain what the "external process" is. If it is just an EXE app that runs on desktop, you can simply use AutoCAD COM API to connect to the running AutoCAD session (or start a new AutoCAD session) and call AcadDocument.SendCommand() method to call your custom command defined in the AutoCAD plugin, as long as it is loaded (say, to make the .NET plugin automatically loaded on startup).

If the "external process" is an unattended app (service kind), then it is not good solution to let the external app to communicate to a AutoCAD session as desktop app, whether via COM communication, or via .ENT API through socket. In this case, you can consider use AutoCAD core console, which can be easily automated by another process (e.g. your "external process") as unattended process; or you can use Design Automation of the Autodesk Platform cloud services: simply loaded your .NET plugin into the core console, or set up your plugin as an Activity of the design automation of the Platform cloud services hosted by Autodesk.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8928
  • AKA Daniel
...
...

A socket sounds interesting, but I’d bet that’s against the EULA..
Something like.. pseudo code
...

..

“allow users to execute”
This part
 

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8928
  • AKA Daniel
I understand, the freecad link was just a curiosity I found while searching for a solution. I have been reading their documentation and it looks like a really good piece of software.

Freecad looks cool, but I’m more of a 2d guy.

I’ve been keeping an eye on ezdxf, https://pypi.org/project/ezdxf/
Has an interface to convert to dwg via ODA DWG-DXF Converter

 

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8928
  • AKA Daniel
AutoCAD core console

Does core console have an onidle event? I was under the impression that console lacked some contexts.
Also, I was not aware you could connect to console via ActiveX, that's cool

Zeftax

  • Newt
  • Posts: 24
  • Measure once, cut thrice, glue, and cut again.
If it is just an EXE app that runs on desktop, you can simply use AutoCAD COM API (...) and call AcadDocument.SendCommand() method.

Yes, that would work great, thank you!
I use Central European Time, dunno why my profile says otherwise.
Pastafarian minister, dungeon master, concertina player, and sometimes I do a bit of CADing as well.

n.yuan

  • Bull Frog
  • Posts: 350
AutoCAD core console

Does core console have an onidle event? I was under the impression that console lacked some contexts.
Also, I was not aware you could connect to console via ActiveX, that's cool

The way of using core console is one core console instance per drawing. So, there is no need to handle event like "OnIdle". For example, you want to process 10 drawings, you start core console 10 times, not like you do with AutoCAD desktop, where the 10 drawings are opened/processed in one AutoCAD instance. Usually, running an instance of core console per drawing is faster than opening the same drawing in AutoCAD desktop and process it - it is comparable to open a side database in AutoCAD desktop. For batch processing, depending on the host hardware, you can run multiple core consoles in parallel.

Yes, core console does not support AutoCAD COM API. If there is really need to communicate with the core console where it runs process a drawing, it is possible to host a socket in the loaded plugin to allow the external app to contact the core console, or to be notified from the core console. However, since it is one session per drawing, and it is quite fast in most cases, it might be very simple and easy to just let the plugin save whatever data (as the result of processing) to a external file (json, xml, text) or database for the external app to pick up.

I did a few EXE apps that drives core console for batch processing. I even have one AutoCAD plugin that drives core console to collect drawing data from a folder (using side database did not need the requirements in this case). This is quite resembles the scenario the OP asked: the EXE, or even the said AutoCAD plugin is the external app, the plugins runs in the core console has the command he wants to run against the drawing, and at the end of each core console session, the core console output (line Editor.WriteMessage() in the plugin code) could be directed to Windows standard output (stream) and easily used by the external EXE.

retsameht

  • Newt
  • Posts: 22
I have some custom commands that I allow users to execute added from a dll. Now, I want to be able to open a drawing and execute a command in it from an external process, has anyone tried that? 
From my research it would seem that the bast way to do it would be to implement IExtensionApplication and in Initialize() start listening to a web socket, to which the external "client" would then send communication, but that seems like an extremely roundabout way of going about it.

WM_COPYDATA

https://forums.autodesk.com/t5/net/generic-routine-to-post-arbitrary-commands-to-the-autocad-prompt/m-p/2196893/highlight/true#M9795