Connecting to an AutoCAD instance from an external EXE including data sharing

Connecting to an AutoCAD instance from an external EXE including data sharing

Anonymous
Not applicable
9,564 Views
18 Replies
Message 1 of 19

Connecting to an AutoCAD instance from an external EXE including data sharing

Anonymous
Not applicable

HI,

I am trying to build a .exe program getting inputs from users and generating an autoCAD file (drawing will be as per the user's input) and an excel sheet (summary of all the used components/blocks).

I followed a solution provided by Kean Walmsley: http://through-the-interface.typepad.com/through_the_interface/2009/05/interfacing-an-external-com-a...

 

Therefore, I am creating in process .dll which contains all the functions that draw on autoCAD (
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;)
My Out process will be user interface and shall send commands to AutoCAD (with parameters).
Your above described post is the solution to my problem. However:

1- I created a class library. I built the "LoadableComponent.DLL" and then I specified "Register for COM interop".

2- I created another windows forms Application (for the out process) and added the loadableComponent.DLL to the references.

 

I am trying to test the above. However, I am having the following error: "Problem in loading application".
and I really appreciate your help with this if possible.


I am using Visual Studio 2015, AutoCAD 2015 and the C# language.

 

I appreciate any possible help,

 

Cheers!

0 Likes
Accepted solutions (1)
9,565 Views
18 Replies
Replies (18)
Message 2 of 19

_gile
Consultant
Consultant

Hi,

 

In the "in process" assembly, you can define AutoCAD Commands (with CommandMethod attribute).

In the "out of process" assembly, using COM Interop, you create a new instance of AutoCAD application from which you can load the "in process" dll calling NETLOAD and then call the defined commands with SendCommand().



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 19

Anonymous
Not applicable

Hi _gile,

Thank you for your reply.I agree, this is a possible solution.

 

 

However, the commands defined within the CommandMethod attribute "cannot take arguments and return nothing."

What if based on the user's input (on the .exe file - radius and (X,Y) position) a certain circle per example should be drawn on the AutoCAD.

 

The in "in process" assembly can call for CIRCLE_CMD which launch a Circle(double Radius, Double X, double Y). I can always ask the user to re-send the required input through the commandLine. But is it possible to send these parameters from the .EXE to the AutoCAD directly?

0 Likes
Message 4 of 19

_gile
Consultant
Consultant
Accepted solution

Here's a trivial minialist example.

 

The out of process part (a Console Application here, but it could be a Window or WPF application as well) in which you:

  • get some user inputs,
  • get or create an AutoCAD instance,
  • create a new drawing from a template,
  • netload the InProcess.dll,
  • call the CIRCLE_CMD defined in InProcess.dll passin it the user inputs.

 

using Autodesk.AutoCAD.Interop;
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace OutOfProcess
{
    class Program
    {
        static void Main()
        {
            // get some user inputs
            double x, y, rad;
            Console.WriteLine("Center X:");
            if (!double.TryParse(Console.ReadLine(), out x)) return;
            Console.WriteLine("Center Y:");
            if (!double.TryParse(Console.ReadLine(), out y)) return;
            Console.WriteLine("Radius:");
            if (!double.TryParse(Console.ReadLine(), out rad)) return;

            // get or create AutoCAD.Application
            AcadApplication acApp = null;
            const string strProgId = "AutoCAD.Application";
            try
            {
                acApp = (AcadApplication)Marshal.GetActiveObject(strProgId);
            }
            catch
            {
                try
                {
                    acApp = (AcadApplication)Activator.CreateInstance(Type.GetTypeFromProgID(strProgId), true);
                }
                catch
                {
                    MessageBox.Show("Cannot create an instance of 'AutoCAD.Application'.");
                    return;
                }
            }
            if (acApp != null)
            {
                try
                {
                    // wait for AutoCAD is visible
                    while (true)
                    {
                        try { acApp.Visible = true; break; }
                        catch { }
                    }
                    var docs = acApp.Documents;

                    // open a new drawing (template)
                    var doc = docs.Add("acadiso.dwt");

                    // netload the InProcess.dll (it have to be in the same folder as OutOfProcess.exe)
                    string filename = Path.Combine(Application.StartupPath, "InProcess.dll");
                    filename = filename.Replace("\\", "\\\\");
                    doc.SendCommand($"(command \"_netload\" \"{filename}\") ");

                    // launch the command defined in InProcess passing it the inputs
                    doc.SendCommand($"CIRCLE_CMD {x},{y} {rad} ");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message);
                }
            }
        }
    }
}

 

 

The "InProcess" code. The command must have prompts corresponding to user inputs. The dll have to be in the same folder as the exe.

 

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace InProcess
{
    public class Commands
    {
        [CommandMethod("CIRCLE_CMD")]
        public void CircleCmd()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            // prompt for center
            var ptRes = ed.GetPoint("\nCircle Center: ");
            if (ptRes.Status != PromptStatus.OK) return;

            // prompt for radius
            var distRes = ed.GetDistance("\nCircle radius: ");
            if (distRes.Status != PromptStatus.OK) return;

            // draw circle
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var model = (BlockTableRecord)tr.GetObject(
                    SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite);
                var circle = new Circle(ptRes.Value, Vector3d.ZAxis, distRes.Value);
                model.AppendEntity(circle);
                tr.AddNewlyCreatedDBObject(circle, true);
                tr.Commit();
            }
        }
    }
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 19

Anonymous
Not applicable

That worked perfectly. In fact, I was looking for the: "doc.SendCommand($"CIRCLE_CMD {x},{y} {rad} ");"

Thank you _gile for your detailed response.

Cheers,

 

Georges

 

0 Likes
Message 6 of 19

Anonymous
Not applicable

Hi,

 

I think it's a bit complicated what you all did.

What about using the AutoCAD Core Console. It's a core of AutoCAD and you can use it as a process in a windows program.

Start the Core Console with a script which contains only the command Netload, the DLL which must be loaded and the command in that DLL.

 

Another think:

Please use

Circle m_Circle = new Circle();

m_Circle.Center = [Point]

 

Not SendCommand because you can get several problem in several situations.

 

Cheers Jürgen

Message 7 of 19

Anonymous
Not applicable

Hi Juergen,

 

The circle thing was just an example. Actually, my intent is to create a windows form application which will be generating 3 documents: an AutoCAD, an excel and a word.

 

I was trying to be able to be connected to AutoCAD externally without the need to "asking" for the same inputs again.

 

Cheers,

Georges

0 Likes
Message 8 of 19

_gile
Consultant
Consultant

@Anonymous

 


Juergen.Becker a écrit :

 

I think it's a bit complicated what you all did.

What about using the AutoCAD Core Console. It's a core of AutoCAD and you can use it as a process in a windows program.

Start the Core Console with a script which contains only the command Netload, the DLL which must be loaded and the command in that DLL.


You're right, using the AutoCAD Core Console could be a solution, but in this case, the script file should have to be written 'on the fly' to pass the command options according the user inputs. I'm not certain it's simpler than my purpose which try to reply to the OP.

 

By my side, I think the simpler way should be avoiding all the out of process stuff and do all the work from a custom AutoCAD command, but this is not what the OP request...

 


Juergen.Becker a écrit :

 

Another think:

Please use

Circle m_Circle = new Circle();

m_Circle.Center = [Point]


Could you explain why ? Is there something wrong with the Circle(Point3d, Vector3d, double) constructor ?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 9 of 19

rlbandeira
Explorer
Explorer

I have successfully tested the web api approach used in this very well designed sample by Norman Yuan

 

http://drive-cad-with-code.blogspot.com.br/search?q=web+api

 

Regards.

0 Likes
Message 10 of 19

Anonymous
Not applicable

Hi,

 

yes you have do make your scriptfile on the fly. But thats simple. An attachment shows how it works. Please change the extension in ".cs".

It's from Augusto an Autodesk man from Brasil.

It's works perfectly.

 

When you are all interesting in a webmeeting I can show you how it works.

 

Regards Jürgen

0 Likes
Message 11 of 19

rlbandeira
Explorer
Explorer

Hi,

 

Thanks for the code. What I like about using "AutoCAD as a service" is that the user can interact from any device like a cell phone or a web browser, as I showed is this pretty old video. In that case, I used wcf. Web api is lighter and easier.

 

https://www.youtube.com/watch?v=A9OoBPHuOwI

 

In that video, I also converted CAD`s geometry into SQL spatial data (using sqlserver.types dll) and got it back from the database into the drawing.

 

Best regards.

 

 

0 Likes
Message 12 of 19

Anonymous
Not applicable

HI,

 

just one question:

Are you in AutoCAD when you connect to the database?

If yes, you don't need the accoreconsole. 

An application can draw the needed objects without any SendCommand.

 

Do you know how an app works?

 

Regards Jürgen

0 Likes
Message 13 of 19

rlbandeira
Explorer
Explorer

Hi,

 

You're absolutely right about the database. The console is very useful to make massive processing like when we're working with thousand of files.

 

Sorry, I didn't understand the question about the app. Do you mean, an external app (.exe) ?

 

Regards.

0 Likes
Message 14 of 19

Anonymous
Not applicable

Hi,

 

I mean: Do you know how a AutoCAD Plugin in C# works?

 

What I saw in that video, that you use SendCommand or similar.  Is the palette I say an AutoCAD Palette?

If yes it's easy do use a .net (C#) Plugin to create the drawing. You can connect to the database, read the table and make all that objects according to the table without any use of SendCommand.

 

Regards Jürgen

0 Likes
Message 15 of 19

rlbandeira
Explorer
Explorer

Hi,

 

Ah, Ok!

 

In that video there's a host running a WCF service inside the AutoCAD (sorry if that's not clear). It's a plugin made in C#. The cell phone and the web application send the geometry to AutoCAD through the service (consumming the service). The plugin then draws the geometry. In fact I don't use the "SendCommand". Thanks for the advice.

 

http://adndevblog.typepad.com/autocad/2013/12/connecting-an-autocad-plug-in-to-an-external-applicati...

 

Guys, please sorry if this conversation has strayed from the original post.

 

Regards.

0 Likes
Message 16 of 19

dgorsman
Consultant
Consultant

@rlbandeira wrote:

Hi,

 

Thanks for the code. What I like about using "AutoCAD as a service" is that the user can interact from any device like a cell phone or a web browser, as I showed is this pretty old video. In that case, I used wcf. Web api is lighter and easier.

 

https://www.youtube.com/watch?v=A9OoBPHuOwI

 

In that video, I also converted CAD`s geometry into SQL spatial data (using sqlserver.types dll) and got it back from the database into the drawing.

 

Best regards.

 

 


You need to be careful about doing such things.  Because it allows multiple users to simultaneously use a single AutoCAD license it can be considered violating the terms of the license agreement.  Note that's different than the core console running unattended on a computer as its still considered a single "user".

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


0 Likes
Message 17 of 19

rlbandeira
Explorer
Explorer

 

Hi, thanks for the advice.

 

I won't "try to fly by the seat of my pants".

 

😉

0 Likes
Message 18 of 19

essam-salah
Collaborator
Collaborator

hi @_gile 

what is the required .dll files for this code.

thanks in advance

0 Likes
Message 19 of 19

_gile
Consultant
Consultant

@essam-salah wrote:

hi @_gile 

what is the required .dll files for this code.

thanks in advance


Which code?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub