Невозможно привести COM-объект типа "System.__ComObject" к интерфейсному типу...

Автор Тема: Невозможно привести COM-объект типа "System.__ComObject" к интерфейсному типу...  (Прочитано 17473 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Пишу модуль для AutoCAD 2014 на VB.NET, который просто перечисляет имена всех листов в текущем документе:

1. Код следующий:

Код - vb.net [Выбрать]
  1.  
  2. Imports System
  3. Imports System.Runtime.InteropServices
  4. Imports System.Windows.Forms
  5.  
  6. Imports Autodesk.AutoCAD.Interop
  7. Imports Autodesk.AutoCAD.Runtime
  8. ...
  9. Public ClassCheckProblem
  10.         <CommandMethod("JustCheckCOM")> _
  11.         Public Sub JustCheckCOM()
  12.             Dim acAppComObj As AcadApplication
  13.             acAppComObj = Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication
  14.             Dim acDocComObj As AcadDocument
  15.             acDocComObj = acAppComObj.ActiveDocument
  16.  
  17.             For i = 0 To acDocComObj.Layouts.Count - 1
  18.                 MsgBox(acDocComObj.Layouts.Item(i).Name)
  19.             Next i
  20.         End Sub
  21. End Class
  22. ...
  23.  

2. Модуль подключаю к AutoCAD с помощью команды NETLOAD.
3. На компьютере, на котором модуль разрабатывался открывается и работает замечательно!
4. Стоит перенести этот модуль на другой компьютер - ВСЁ, ПРИЕХАЛИ... получаем следующее сообщение:




Что можно сделать в таком случае?









Подробная информация об использовании оперативной
(JIT) отладки вместо данного диалогового
окна содержится в конце этого сообщения.

************** Текст исключения **************
System.InvalidCastException: Невозможно привести COM-объект типа "System.__ComObject" к интерфейсному типу "Autodesk.AutoCAD.Interop.AcadApplication". Операция завершилась со сбоем, поскольку вызов QueryInterface COM-компонента для интерфейса с IID "{070AA05D-DFC1-4E64-8379-432269B48B07}" возвратил следующую ошибку: Интерфейс не поддерживается (Исключение из HRESULT: 0x80004002 (E_NOINTERFACE)).
   в ACAD_NET_PDF.ACADPDF.GetAFoo.football()
   в Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   в Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   в Autodesk.AutoCAD.Runtime.PerDocumentCommandClass.Invoke(MethodInfo mi, Boolean bLispFunction)
   в Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()


Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Что-то было такое... Попробуйте заменить: Dim acAppComObj As AcadApplication на Dim acAppComObj As IAcadApplication

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Попробовал! IAcadApplication и даже IAcadDocument сделал )))

На моей машине работает, на чужой - увы, нет!

Может еще какое-нибудь решение есть

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Надо смотреть как библиотеки подключены, может там проблема...
А зачем через COM? Это же можно на чистом NET сделать.

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Проблема в том, что COM объект я знаю хорошо, а чистый NET - как китайская грамота ))) Но это пока, так-то я быстро учусь - учителя нет!

Подскажите, как бы вы сделали перебор всех листов в текущем чертеже и показали бы названия их установленных принтеров с помощью NET?

В случае VBA/ActiveX/COM это выглядело бы так:

Код - vb.net [Выбрать]
  1.     Public Class ShowPrintersAllLayouts
  2.         <CommandMethod("ShowPrinters")> _
  3.         Public Sub ShowPrinters()
  4.  
  5.             Dim acAppComObj As IAcadApplication
  6.  
  7.             acAppComObj = Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication
  8.  
  9.             Dim acDocComObj As IAcadDocument
  10.  
  11.             acDocComObj = acAppComObj.ActiveDocument
  12.  
  13.             For i = 0 To acDocComObj.Layouts.Count - 1
  14.  
  15.                 MsgBox(acDocComObj.Layouts.Item(i).ConfigName)
  16.  
  17.             Next i
  18.  
  19.         End Sub
  20.     End Class


На компьютерах с установленным Visual Studio и AutoCAD это работает. На других - нет.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Подскажите, как бы вы сделали перебор всех листов в текущем чертеже и показали бы названия их установленных принтеров с помощью NET?
Наверное, на основе этого бы делал: http://through-the-interface.typepad.com/through_the_interface/2007/09/driving-a-basic.html
Для получения всех листов (имен), у меня есть такой вспомогательный метод:
Код - C# [Выбрать]
  1. /// <summary>
  2. /// Получение списка имен листов в чертеже
  3. /// </summary>
  4. /// <param name="db">База данных чертежа</param>
  5. /// <param name="noModel">true - список имен только листов, false - список имен листов и модели</param>
  6. /// <returns>Список имен листов</returns>
  7. public static string[] GetLayoutNames(this Database db, bool noModel = true)
  8. {
  9.     List<string> retVals = new List<string>();            
  10.     using (Transaction tr = db.TransactionManager.StartTransaction())
  11.     {
  12.         DBDictionary layoutDict = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
  13.         foreach (DBDictionaryEntry dbDictEnt in layoutDict)
  14.             retVals.Add(dbDictEnt.Key);
  15.         tr.Commit();
  16.     }
  17.  
  18.  
  19.     if (noModel)
  20.     {
  21.         //Удаляем из данных о листах модель            
  22.         retVals.Remove("Model");
  23.     }
  24.     return retVals.ToArray();
  25. }

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Ясно, вроде буквы знакомые, а только не понятно ничего... Что такое транзакция? Вообще для чего она нужна, какую роль она выполняет?

... OpenMode.ForRead - это зачем вообще? Типа получаем массив названий листов...
а если надо будет изменить имя листа, то надо будет выгрузить массив данных, изменить его, а потом загрузить массив в DBDictionary?
А где-то есть просто Layout(i).Name="Имя"? Без заморочек с какой-то транзакцией и т.д.?
Я даже не понял в какой строчке Вашего кода выводится название листа.

Мне же просто нужно подключиться к текущему чертежу и взять имена принтеров его листов...
Я не понимаю как это работает. Извини. Пятница - очень устал от безрезультатных действий.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Ну так это же азы NET программирования под автокад. Если планируется писать плагины для автокада на NET, то надо пройти базовое обучение. Благо, есть возможности и на тренинге это сделать (скоро AU2015Russia, обычно, в это же время тренинги для программистов проходят), и самостоятельно, например, с помощью таких материалов: http://usa.autodesk.com/adsk/servlet/index?id=18162650&siteID=123112
Конечно, если это разовая задача - то можно разобраться, почему COM не работает, исправить и остановиться на этом.

Оффлайн German

  • ADN Club
  • **
  • Сообщений: 84
  • Карма: 13
Как говорит автор прекрасного сайта https://sites.google.com/site/bushmansnetlaboratory/, RTFM.
Без обид, просто я начинал с этого. Тогда на русском материалов было очень мало.

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Что такое транзакция? Вообще для чего она нужна, какую роль она выполняет?

... OpenMode.ForRead - это зачем вообще? Типа получаем массив названий листов...
а если надо будет изменить имя листа, то надо будет выгрузить массив данных, изменить его, а потом загрузить массив в DBDictionary?
А где-то есть просто Layout(i).Name="Имя"? Без заморочек с какой-то транзакцией и т.д.?
Я даже не понял в какой строчке Вашего кода выводится название листа.
А что, уже и гугл забанили? Не ленись юзать поиск: тынц, тынц.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
На компьютерах с установленным Visual Studio и AutoCAD это работает. На других - нет.
Обрати внимание на следующие моменты:
1. Компилировать обязательно в режим Release, а не Debug.
2. Версии AutoCAD должны совпадать.
3. Разрядность (x86/x64) AutoCAD должна совпадать (это в случае использования COM/Interop как у тебя.)
Если хотя бы одно из условий не выполняется - будет ошибка при выполнении.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Windcastle

  • ADN OPEN
  • **
  • Сообщений: 58
  • Карма: 0
Александр, спасибо за ответ. Это я Пашин Евгений. Пришлось зарегистрироваться заново. Буду писать с этого логина - из дома, с другого - с работы! Не пойму, почему меня не пускают на форум по рабочему логину )

1. Компилировать в режиме Release! Я правильно понимаю Вашу рекомендацию?



При сборке решения, папка Release - пустая! DLL сохраняется в папке Debug!

2. Версии AutoCAD должны совпадать!

AutoCAD 2014 для Windows 8.1 (x64) и AutoCAD 2014 для Windows XP (x64) - это я могу считать одинаковыми версиями?
Только у Windows XP NetFramework 4, а у Windows 8.1 NetFramework 4.5! Но компилирую под NetFramework 4!

3. Разрядность x64 у обеих машин!

Прошу Вас, сделайте то, что сделал я: код я выложил выше. Он ужасно простой. Попробуйте подгрузить библиотеку в AutoCAD на машине с установленным Visual Studio и на машине, где нет Visual Studio (даже пусть это будет другая машина - Windows 7 x64 к примеру). Если у Вас получится, то я больше не буду задавать Вам этот вопрос. И отстану! Приму тот факт, что это у меня какие-то проблемы с понимаем.

Мне нужно решение, которое я смогу запускать на любых машинах, а не на отдельно взятой или с похожими характеристиками. Прошу Вас, не проигнорируйте мою просьбу.


Код - vb.net [Выбрать]
  1. Public Class ShowPrintersAllLayouts
  2.         <CommandMethod("ShowPrinters")> _
  3.         Public Sub ShowPrinters()
  4.  
  5.             Dim acAppComObj As IAcadApplication
  6.  
  7.             acAppComObj = Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication
  8.  
  9.             Dim acDocComObj As IAcadDocument
  10.  
  11.             acDocComObj = acAppComObj.ActiveDocument
  12.  
  13.             For i = 0 To acDocComObj.Layouts.Count - 1
  14.  
  15.                 MsgBox(acDocComObj.Layouts.Item(i).ConfigName)
  16.  
  17.             Next i
  18.  
  19.         End Sub
  20.     End Class



И еще! У меня дома стоит AutoCAD 2016 x64 - я принес эту библиотеку с работы, чтобы попробовать! Работает! Почему? И даже конфигурационный файл acad.exe.config не трогал.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Windcastle, Выложи полный проект (в zip-архиве).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Мне нужно решение, которое я смогу запускать на любых машинах, а не на отдельно взятой или с похожими характеристиками.
Этого сделать нельзя. Или тебе придётся извращаться с поздним связыванием или Reflection. Проще написать несколько dll-файлов в зависимости от версии и разрядности AutoCAD.
3. Разрядность x64 у обеих машин!
Точно? x64 на XP - это большая редкость.

При сборке решения, папка Release - пустая! DLL сохраняется в папке Debug!
Потому что активная конфигурация - DEBUG.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Не пойму, почему меня не пускают на форум по рабочему логину )
Или неверный логин, или неверный парооль. Других причин нет.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Windcastle

  • ADN OPEN
  • **
  • Сообщений: 58
  • Карма: 0
Точно? x64 на XP - это большая редкость.

Сам был удивлен, когда увидел на виртуальной машине эту операционку поскольку мне не приходилось работать с такой версией )

Потому что активная конфигурация - DEBUG.

Как это исправить?

Или неверный логин, или неверный пароль. Других причин нет.

Проверю только завтра.

Windcastle, Выложи полный проект (в zip-архиве).

Могу только библиотеку выложить сейчас, а весь проект в архиве - только завтра (с работы!). Мне незачем Вам врать, что даже AutoCAD 2016 его воспринимает! Можете проверить и у себя. Но уверяю, весь проект выложу завтра с работы, а dll - выложить сейчас? Есть еще один проект с работы, но там есть кроме нужного кода еще и мусор всякий, но зато он хоть будет потверждением того, что я не соврал! Я запустил dll c папки проекта и AutoCAD 2016 даже слова мне не сказал ))) Могу его выложить!

Оффлайн Windcastle

  • ADN OPEN
  • **
  • Сообщений: 58
  • Карма: 0
Только что попробовал дома написать тот же самый код на Visual Basic 2012 под Net Framework 4 и мне Visual Studio "кукишь с маслом прописал"!!!

Ну что это такое-то?







Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Откуда ты берёшь (из какого каталога) AutoCAD'овские сборки? Небось из каталога AutoCAD 2016?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Windcastle

  • ADN OPEN
  • **
  • Сообщений: 58
  • Карма: 0

Отмечено как Решение Пашин Евгений 24-08-2015, 06:58:37

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
АГА! А в чем подвох?
Подвох в том, что в AutoCAD 2016 acmgd.dll, accoremgd.dll и acdbmgd.dll скомпилированы с .NET 4.5
И соответственно ты не можешь ссылаться на них в проекте, который собирается с .NET 4.0
Ты должен сделать следующее (для версий 2014...2016):
1. Скачать и запустить инсталляцию ObjectARX SDK 2014: http://download.autodesk.com/esd/objectarx/2014/Autodesk_ObjectARX_2014_Win_64_and_32Bit.sfx.exe
2. Ссылаться в своём проекте на AutoCAD'овские .NET библиотеки из ObjectARX SDK (они в каталоге C:\ObjectARX 2014\inc)
3. Использовать в конфигурации проекта .NET 4.0
Если ты не будешь использовать COM/ActiveX, то и будешь использовать конфигурацию Release, то в AutoCAD 2014...2016 x86/x64 твоя сборка должна работать.
Если ты будешь использовать COM/ActiveX (а у тебя именно так), то тебе придётся сделать или два проекта или две конфигурации (одну для x86 и одну для x64).
В них подключаешь Autodesk.AutoCAD.Interop.dll и Autodesk.AutoCAD.Interop.Common.dll из каталога C:\ObjectARX 2014\inc-Win32 или ObjectARX 2014\inc-x64 в зависимости от того, для какой разрядности AutoCAD делаешь сборку.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Посмотрел твой архив и ужаснулся. Мне еще долго придётся приходить в себя. Почему у тебя все AutoCAD'овские сборки оказались в каталоге bin\Debug? Вот и будет у тебя сборка работать только в той версии AutoCAD, из которой эти сборки скопированы. Ты ставил для подключенных сборок AutoCAD CopyLocal в False?
Использование русских имён переменных и имён функций я даже обсуждать не буду - для меня это моветон.

Посмотри эту картинку:

« Последнее редактирование: 23-08-2015, 22:45:49 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Windcastle

  • ADN OPEN
  • **
  • Сообщений: 58
  • Карма: 0
Если сработает, буду каждый час Вам карму плюсовать пока пальцы не устанут )))

А насчет NET Framework 4.5 уточню... может последний раз и под него скомпилировал... играл с проектом.

P.S. Не понимаю, почему мы сразу с этого не начали... может уже бы проект сдал )))

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Ты ставил для подключенных сборок AutoCAD CopyLocal в False?

Да, пришлось это сделать, потому что не было ясности, в чем проблема, пробовал даже нелепые варианты.

Использование русских имён переменных и имён функций я даже обсуждать не буду - для меня это моветон.

На работоспособность не влияет? Нет. Может мы это оставим как выбор каждого из нас?

Пробую Ваши рекомендации. Сразу отпишусь, как сделаю! Спасибо Вам за подробное описание действий.

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Александр, не знаю как отблагодарить! Работает! Так просто всё оказалось, без лишнего шума. Толково объяснили, теперь у меня все сдвинулось с места. Я смогу сдать проект в таком виде (в виде двух библиотек). А теперь можно и вплотную NET AutoCAD будет заняться. У меня руки развязаны. А проект переделать успею под NET!

Боюсь, что я теперь этот форум замучаю вопросами )))


Решением нужно отметить не только текст, но и все изображения!!!

Оффлайн Doublefish

  • ADN Club
  • ****
  • Сообщений: 288
  • Карма: 10
  • AutoCAD Civil 3D
Обрати внимание на следующие моменты:1. Компилировать обязательно в режим Release, а не Debug.2. Версии AutoCAD должны совпадать.3. Разрядность (x86/x64) AutoCAD должна совпадать (это в случае использования COM/Interop как у тебя.)Если хотя бы одно из условий не выполняется - будет ошибка при выполнении.

По поводу п.1 - если debug, то на другом компьютере работать будет если автокад той же версии, проверено на .NET. Или я может что-то не так понял?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Имеется в виду, что на другом компьютере не установлено Visual Studio. Возможно это лишняя перестраховка. Но однозначно для чистого ObjectARX (неуправляемый C++) требуется компиляция в Release, для того чтобы на другом компьютере без Visual Studio этот код загрузился в AutoCAD и заработал.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение