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();
}
}
}
}