Как я могу открыть AutoCAD 2015 через .NET API

Я проработал хороший час и еще не нашел что-то, что поможет в этом. Я работаю над открытием AutoCAD из .NET API в VS2013 с использованием С#, но по какой-то причине я никогда не смогу запустить AutoCAD. Я использую следующий код:

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:\Users\Administrator\Documents\All Code\main-libraries\IOAutoCADHandler\bin\Debug\IOAutoCADHandler.dll" + (char)34 + ") ");

            acDocComObj.SendCommand("DRAWCOMPONENT");
        }
    }

К сожалению, он всегда останавливается в вложенном операторе catch и всегда отображает всплывающее окно без открытия AutoCAD. Любые предложения о том, как хотя бы сделать AutoCAD для меня?

EDIT: сообщение об ошибке
][1

Ответ 1

Проблема в том, что вы кодируете (правильно) интерфейс InterCAD. Я рекомендую против этого (из-за возможных изменений версии).

Другая проблема заключается в том, что документация для плагинов AutoCAD, использующая новый .net api, предназначена для плагинов, когда AutoCAD уже запущен.

Конечная проблема может заключаться в том, что идентификатор программы AutCAD является загадкой. Я прибегал к настройке настраиваемого параметра, но по умолчанию используется значение "AutoCAD.Application", которое примет зарегистрированный в настоящее время AutoCAD.Application на производственной машине. Если на компьютере установлено несколько версий, и вы хотите быть конкретными, то вы можете добавить номер версии (который вам потребуется исследовать) в ProgID, например: "AutoCAD.Application.19" или "AutoCAD.Application.20" на 2015 год.

Для первой проблемы один метод - использовать динамику для объектов autoCad, особенно для создания экземпляров. Я использовал ObjectARX api для создания своего приложения в фиктивном проекте, а затем переключился на динамику, когда я доволен именами свойств и методов.

В автономном приложении .Net, которое запускает AutoCAD, вы можете использовать что-то вроде:

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

Ответ 2

Я открываю приложение очень прямолинейно. Во-первых, обязательно обратитесь к правильной библиотеке типов. Я использую библиотеку типов AutoCAD 2014, расположенную по адресу: c:\program files\common files\autodesk shared\acax19enu.tlb

Для инициализации приложения:

using AutoCAD;

namespace test
{
class Program
{
    static void Main(string[] args)
    {
        AutoCAD.AcadApplication app;

        app = new AcadApplication();

        app.Visible = true;

        Console.Read();
    }
}
}

Ответ 3

Если на компьютере установлено несколько версий AutoCAD, создание экземпляра с помощью ProgID "AutoCAD.Application" будет запускать последнюю версию, запущенную на этом компьютере текущим пользователем. Если версия используемой сборки Interop не соответствует версии, которая запускается, вы получите исключение System.InvalidCastException с HRESULT 0x80004002 (E_NOINTERFACE).

В вашем конкретном случае {070AA05D-DFC1-4E64-8379-432269B48B07} IID в вашем сообщении об ошибке является GUID для интерфейса AcadApplication в 64-разрядном R19 (AutoCAD 2013 и 2014). Таким образом, запускается AutoCAD 2013 или 2014, и вы не можете использовать этот COM-объект для типа 2015, потому что 2015 - это R20 (не совместим с бинарными).

Чтобы этого избежать, вы можете добавить определенную версию в свой ProgID (например, "AutoCAD.Application.20" для AutoCAD 2015 (R20.0) до 2016 (R20.1)), чтобы запустить версию, соответствующую вашим сборкам Interop или вы можете использовать позднюю привязку (например, удалите свои ссылки на Autodesk.AutoCAD.Interop * и используйте ключевое слово dynamic вместо типов AutoCAD).

В последнем случае вы потеряете автозаполнение, но ваша программа будет работать со всеми версиями AutoCAD.

Проверьте также 32-разрядные и 64-разрядные, поскольку сборки TypeLib/Interop не совпадают.

Ответ 4

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Tekkit
{
    class Program
    {
        static void Main(string[] args)
        {

                //make sure to add last 2 using statements
                ProcessStartInfo start = new ProcessStartInfo("calc.exe");                              
                Process.Start(start);//starts the process

        }
    }
}