3

I am writing a program using a Windows Form in C# that models 3d objects and then is supposed to open AutoCAD from the .NET framework to draw the objects, and I'm trying to figure out the best way to do that.

I've tried previously opening AutoCAD from .NET using COM, but I was wondering if there was perhaps a way that didn't end in a no such interface supported error, as every avenue I've tried (opening a drawing, opening AutoCAD using COM, etc.) have ended without results. Any suggestions?

Community
  • 1
  • 1
Archer
  • 492
  • 1
  • 4
  • 12

2 Answers2

5

When I'm doing this type of thing, I just start AutoCAD with System.Diagnostics.Process and make sure to pass in an AutoCAD script file at startup:

System.Diagnostics.Process proc = new Process();
proc.StartInfo.FileName = @"C:\Program Files\AutoCAD 2010\acad.exe /b myScriptFile.scr";
proc.Start();

Instead of trying to manipulate AutoCAD directly from .NET which, as you have found, can be problematic, I just write all my AutoCAD commands to the script file, and then send that script file to AutoCAD as a command line argument as shown above.

Stewbob
  • 16,759
  • 9
  • 63
  • 107
  • This works well if you don't need to really touch the application once it's running. Viru from AutoDesk used this same approach when he authored ScriptPro. – Parrish Husband Jun 26 '14 at 13:13
  • You can include wait points in the script file to pause for some (limited) user input while the script is running. – Stewbob Jun 26 '14 at 13:16
  • 1
    I meant in the context of .NET talking to and/or controlling things in real-time. Most often with this approach it's a good idea to add in an idle operation timer to force-restart AutoCAD if something hangs. Since the OP's Interop method wouldn't work though, your approach is the logical choice here. – Parrish Husband Jun 26 '14 at 13:27
0

I use the example you displayed, but I try to get the active Autocad first. You could combine this with using process as mentioned in the previous answer, but that requires always knowing where Autocad is installed to.

try
{
  // you may choose to reverse this, by calling getActiveObject first
  // or you can try repeating the getActiveObject after a short delay
  var t = Type.GetTypeFromProgID(_autocadClassId, true);
  // Create a new instance AutoCAD
  _application = Activator.CreateInstance(t, true);      
}
catch (COMException ex)
{
    try
    {
        // Start works every time, but due to the delay it may appear not to
        // check task manager when testing this
        // add a delay here before trying to get what was started
        Thread.Sleep(750); //for example
        _application = Marshal.GetActiveObject(_autocadClassId);
    }
    catch (Exception e2x)
    {
        Log.Error(e2x);
    }
}

My _application object is a dynamic, I have a CAD class with static methods that encapsulates AutoCAD functionality, for adding new features, I have a dummy project with the CAD class that uses the AutoCAD interop to get the methods and property names and casing right, but I deploy with the dynamic.

reckface
  • 5,678
  • 4
  • 36
  • 62