Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I've been browsing for a good hour and have yet to find something that would help with this. I'm working on opening AutoCAD from the .NET API in VS2013 using C#, but for some reason, I can never get AutoCAD to actually launch. I'm using the following code:

using System;
using System.Runtime.InteropServices;

using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;

namespace IOAutoCADHandler
{
    public static class ACADDocumentManagement
    {
        [CommandMethod("ConnectToAcad")]
        public static void ConnectToAcad()
        {

            AcadApplication acAppComObj = null;
            // no version number so it will run with any version
            const string strProgId = "AutoCAD.Application";

            // Get a running instance of AutoCAD
            try
            {
                acAppComObj = (AcadApplication)Marshal.GetActiveObject(strProgId);
            }
            catch // An error occurs if no instance is running
            {
                try
                {
                    // Create a new instance of AutoCAD
                    acAppComObj = (AcadApplication)Activator.CreateInstance(Type.GetTypeFromProgID(strProgId), true);
                }
                catch   //// STOPS HERE
                {
                    // If an instance of AutoCAD is not created then message and exit
                    // NOTE: always shows this box and never opens AutoCAD
                    System.Windows.Forms.MessageBox.Show("Instance of 'AutoCAD.Application'" +
                                                         " could not be created.");

                    return;
                }
            }

            // Display the application and return the name and version
            acAppComObj.Visible = true;
            System.Windows.Forms.MessageBox.Show("Now running " + acAppComObj.Name +
                                                 " version " + acAppComObj.Version);

            // Get the active document
            AcadDocument acDocComObj;
            acDocComObj = acAppComObj.ActiveDocument;

            // Optionally, load your assembly and start your command or if your assembly
            // is demandloaded, simply start the command of your in-process assembly.
            acDocComObj.SendCommand("(command " + (char)34 + "NETLOAD" + (char)34 + " " +
                                    (char)34 + @"C:UsersAdministratorDocumentsAll Codemain-librariesIOAutoCADHandlerinDebugIOAutoCADHandler.dll" + (char)34 + ") ");

            acDocComObj.SendCommand("DRAWCOMPONENT");
        }
    }

Unfortunately, it always stops at the nested catch statement and always displays the popup box without opening AutoCAD. Any suggestions on how to at least make AutoCAD open for me?

EDIT: Error message
][1

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
346 views
Welcome To Ask or Share your Answers For Others

1 Answer

The issue is you're coding (correctly) to the AutoCAD interop interface. I recommend against that (due to potential version changes).

The other issue is that the documentation for AutoCAD plugins using the newer .net api is for plugins when AutoCAD is already running.

Final issue could be that the program Id of AutCAD is a mystery. I have resorted to making that a configurable setting, but default to "AutoCAD.Application", which will take the currently registered AutoCAD.Application on the production machine. If there are multiple versions installed on the machine and you want to be specific, then you could append the version number (which you'll need to research) to the ProgID like: "AutoCAD.Application.19", or "AutoCAD.Application.20" for 2015.

For the first issue, one technique is to use dynamics for the autoCad objects, particularly for creating instances. I have used the ObjectARX api for creating my application in a dummy project, and then switching to dynamics when I'm happy with the properties and method names.

In a standalone .Net application that starts AutoCAD you could use something like:

// I comment these out in production
//using Autodesk.AutoCAD.Interop;
//using Autodesk.AutoCAD.Interop.Common;
//...
//private static AcadApplication _application;
private static dynamic _application;
static string _autocadClassId = "AutoCAD.Application";

private static void GetAutoCAD()
{
    _application = Marshal.GetActiveObject(_autocadClassId);
}

private static void StartAutoCad()
{
    var t = Type.GetTypeFromProgID(_autocadClassId, true);
    // Create a new instance Autocad.
    var obj = Activator.CreateInstance(t, true);
    // No need for casting with dynamics
    _application = obj;
}

public static void EnsureAutoCadIsRunning(string classId)
{
    if (!string.IsNullOrEmpty(classId) && classId != _autocadClassId)
        _autocadClassId = classId;
    Log.Activity("Loading Autocad: {0}", _autocadClassId);
    if (_application == null)
    {
        try
        {
            GetAutoCAD();
        }
        catch (COMException ex)
        {
            try
            {
                StartAutoCad();
            }
            catch (Exception e2x)
            {
                Log.Error(e2x);
                ThrowComException(ex);
            }
        }
        catch (Exception ex)
        {
            ThrowComException(ex);
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...