Ошибка при открытии разных версий AutoCAD

Программа, над которой я работаю, будет использоваться в AutoCAD 2013 и 2002. Итак, что я делаю, так это проверяю, есть ли у пользователя 2013, и если его нет, попробуйте 2002. Проблема возникает, когда код связывает объект AcadApplication к открытому экземпляру 2002 года.

код:

_progID_2002 = "AutoCAD.Application.15";
_progID_2013 = "AutoCAD.Application.19";

try
{
    Type acType = Type.GetTypeFromProgID(_progID_2002);
    _acadApp = (AcadApplication)Activator.CreateInstance(acType, true);
}
catch
{
    // Try other version, or exit
}

Так что это отлично работает, когда я использую _progID_2013. Он открывает AutoCAD 2013 и _acadApp получает ссылку. Когда я пробую это с _progID_2002, он открывает AutoCAD 2002, но когда я устанавливаю _acadApp для открытого экземпляра, он выдает исключение:

InvalidCastException
Unable to cast COM object of the type 'System._ComObject' to interface type   
'AutoCAD.AcadApplication'. This operation failed because the QueryInterface 
call on the COM component for the interface with IID '{070AA05D-DFC1-4E64-
8379-432269B48B07}' failed due to the following error: No such interface
supported (Exception from HRESULT:0x80004002 (E_NOINTERFACE)).

Я безуспешно пытался использовать библиотеки взаимодействия 2000 и 2013 годов.


person Natzely    schedule 27.09.2013    source источник


Ответы (2)


Проблема не в версии, поскольку вы используете COM для получения AutoCAD. Вызовы GetObject работали еще во времена VB6, поэтому дело не в том, что объект AutoCAD.Application.15 невозможно создать, а в том, что вы пытаетесь привести его к определенному типу, которому он не соответствует. В вашем проекте какую сборку вы загрузили, которая определяет тип AcadApplication? Я могу гарантировать вам, что версии 2002 и 2013 годов плохо сочетаются друг с другом.

Я бы построил этот проект в .NET 4.0 и сделал бы _acadApp динамической переменной.

Dynamic _acadApp;
try
{
    Type acType = Type.GetTypeFromProgID(_progID_2002);
    _acadApp = Activator.CreateInstance(acType, true);
}

Это будет означать, что у вас не будет никакого интеллекта во время написания, и он будет скомпилирован, даже если вы ввели методы/свойства, которых не существует. Это означает, что у вас могут быть методы, которые работают для 2002, а не для 2013, и наоборот. Если вам нужно использовать .NET 3.5 или более раннюю версию, вам подойдет Reflection.

person Parrish Husband    schedule 28.09.2013
comment
Спасибо, подожду понедельника, попробую. Я дам Вам знать. - person Natzely; 28.09.2013
comment
Итак, я переключил _acadApp на динамический, и он не выдает мне ошибку, когда я устанавливаю _acadApp, но всякий раз, когда я пытаюсь получить что-то из него, например, ActiveDocument или SelectionSet, он выдает мне ошибку. Итак, мне пришлось переключить любой объект Acad, который я использовал, на динамический, чтобы заставить его работать. К счастью, поскольку у меня уже все было настроено, мне не нужно было беспокоиться о том, что у меня нет интеллигенции. Я узнал еще кое-что. Я также опубликую это как ответ. - person Natzely; 30.09.2013
comment
Рад, что ты разобрался. Мне нравится делать то же самое, что и вы, а именно писать код, используя сборки COM (учитывая, что мне нужен COM вместо внутреннего API), а затем, когда он готов к запуску, я удаляю ссылки и изменяю необходимые типы, чтобы они были динамическими. Отлично работает с приложениями Office без необходимости возиться с зависимостями версий. - person Parrish Husband; 01.10.2013

Возясь с ответом, который дал Локк, я обнаружил, что если я запустил приложение как x64 вместо x86, приложение будет работать с Acad 2002. Мне нужно использовать библиотеку объектов 2000, и она больше не будет открывать 2013 из-за та же ошибка. Итак, мне нужно создать две разные версии приложения. Одна для версии 2002 года работает как x64, а другая для версии 2013 года, которая будет работать как с x64, так и с x86. Кто-то умнее меня, вероятно, мог бы сказать нам, почему.

person Natzely    schedule 30.09.2013