Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: vermesser от 29-12-2015, 14:49:11

Название: Assembly.LoadFrom работает раз через раз
Отправлено: vermesser от 29-12-2015, 14:49:11
Добрый день!

Вкратце опишу свою проблему:

Есть сборка, загружаемая в Autocad по NETLOAD.
В её коде инициализации загружается внешняя библиотека через Assembly.LoadFrom().

Так вот эта внешняя сборка загружается не всегда,
а совершенно непредсказуемо:
на некоторых компьютерах через раз, через два - как попало;
на каких-то компьютерах загружается всегда,
а на каких-то никогда вообще.

Вот код:

Код - vb.net [Выбрать]
  1. Imports Autodesk.AutoCAD.Runtime
  2. Imports Autodesk.AutoCAD.ApplicationServices
  3. Imports Autodesk.AutoCAD.EditorInput
  4. Imports System.Reflection
  5.  
  6. Public Class Initialization
  7.  
  8.     Implements Autodesk.AutoCAD.Runtime.IExtensionApplication
  9.  
  10.     Public Sub Initialize() Implements IExtensionApplication.Initialize
  11.         Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
  12.         Try
  13.             Assembly.LoadFrom(".\Extensions\octree.dll")
  14.             ed.WriteMessage(vbCrLf & "Модуль Octree Search загружен")
  15.         Catch
  16.             ed.WriteMessage(vbCrLf & "Сбой загрузки модуля Octree Search")
  17.         End Try
  18.     End Sub
  19.  
  20.     Public Sub Terminate() Implements IExtensionApplication.Terminate
  21.         Console.WriteLine("Работа завершена")
  22.     End Sub
  23.  
  24. End Class

Если перехватывать код ошибки так:

Код - vb.net [Выбрать]
  1. Try
  2.     Assembly.LoadFrom(".\Extensions\octree.dll")
  3.     ed.WriteMessage(vbCrLf & "Модуль Octree Search загружен")
  4. Catch ex As Exception
  5.     ed.WriteMessage(vbCrLf & "Модуль Octree Search загружен: " & ex.HResult)
  6. End Try

Получаем:

Сбой загрузки модуля Octree Search: -21470248941
Но о такой ошибке ничего не знает даже Гугл.

Курение мануалов не помогает.
Название: Re: Assembly.LoadFrom работает раз через раз
Отправлено: Александр Ривилис от 29-12-2015, 14:51:59
Грузи по абсолютному пути, а не по относительному и думаю что будет всё нормально.
Название: Re: Assembly.LoadFrom работает раз через раз
Отправлено: Андрей Бушман от 29-12-2015, 14:52:17
В последних нескольких версиях AutoCAD твой код метода Initialize может аварийно завершаться, т.к. ты не проверяешь Application.DocumentManager.MdiActiveDocument на равенство null.
Название: Re: Assembly.LoadFrom работает раз через раз
Отправлено: vermesser от 29-12-2015, 14:57:40
Грузи по абсолютному пути, а не по относительному и думаю что будет всё нормально.
Спасибо!
То есть, если я правильно понимаю, то мне следует сначала получать путь,
по которому находится основная сборка и дописывать к нему путь до внешней сборки
и после этого скармливать то, что получится методу Assembly.LoadFrom()?
Название: Re: Assembly.LoadFrom работает раз через раз
Отправлено: vermesser от 29-12-2015, 15:04:07
В последних нескольких версиях AutoCAD твой код метода Initialize может аварийно завершаться, т.к. ты не проверяешь Application.DocumentManager.MdiActiveDocument на равенство null.
Аварийное завершение будет происходить в том случае если активное окно не является окном чертежа?
Название: Re: Assembly.LoadFrom работает раз через раз
Отправлено: Александр Ривилис от 29-12-2015, 15:04:22
То есть, если я правильно понимаю, то мне следует сначала получать путь,
по которому находится основная сборка и дописывать к нему путь до внешней сборки
и после этого скармливать то, что получится методу Assembly.LoadFrom()?
Именно. То, как ты сейчас задаёшь путь зависит от текущего каталога AutoCAD. Относительный каталог берётся не относительно каталога твоей основной сборки, а относительно текущего каталога AutoCAD. Мне не очень понятно почему у тебя вообще что-то работало. Насколько я помню многие операции (например, открытие dwg-файла в AutoCAD) приводят к изменению текущего каталога в некоторых версиях AutoCAD. Возможно и команда _NETLOAD обладает таким свойством. Так что единственный надёжный путь - задавать абсолютный путь.
Название: Re: Assembly.LoadFrom работает раз через раз
Отправлено: vermesser от 29-12-2015, 15:07:02
То есть, если я правильно понимаю, то мне следует сначала получать путь,
по которому находится основная сборка и дописывать к нему путь до внешней сборки
и после этого скармливать то, что получится методу Assembly.LoadFrom()?
Именно. То, как ты сейчас задаёшь путь зависит от текущего каталога AutoCAD. Относительный каталог берётся не относительно каталога твоей основной сборки, а относительно текущего каталога AutoCAD. Мне не очень понятно почему у тебя вообще что-то работало. Насколько я помню многие операции (например, открытие dwg-файла в AutoCAD) приводят к изменению текущего каталога в некоторых версиях AutoCAD. Возможно и команда _NETLOAD обладает таким свойством. Так что единственный надёжный путь - задавать абсолютный путь.
Спасибо Вам за оперативный ответ.
Я сделаю так.
Название: Re: Assembly.LoadFrom работает раз через раз
Отправлено: Александр Ривилис от 29-12-2015, 15:12:11
Наводка: http://adn-cis.org/forum/index.php?topic=3062.0
Название: Re: Assembly.LoadFrom работает раз через раз
Отправлено: Александр Ривилис от 29-12-2015, 20:09:50
Аварийное завершение будет происходить в том случае если активное окно не является окном чертежа?
Да. Или нет ни одного окна.
Название: Re: Assembly.LoadFrom работает раз через раз
Отправлено: vermesser от 29-12-2015, 21:25:08
Аварийное завершение будет происходить в том случае если активное окно не является окном чертежа?
Да. Или нет ни одного окна.
У меня на этот случай свой велосипед написан ))))))))))))))
Код - vb.net [Выбрать]
  1.     'Вернёт истину, если открытое окно - это окно документа, и ложь, если нет.
  2.     Public Function CheckDocumentType(ByVal chkDoc As Document) As Boolean
  3.         Try
  4.             Dim docName As String = chkDoc.Name 'Тут можем получить ошибку, т.к. свойство .Name есть только у окон документов
  5.             Return True
  6.         Catch ex As NullReferenceException
  7.             Return False
  8.         End Try
  9.     End Function
Вызываю так:
Код - vb.net [Выбрать]
  1. Dim isDrawing As Boolean = CheckDocumentType(Application.DocumentManager.MdiActiveDocument)
Какой же я всё-таки находчивый парень ))))))
Название: Re: Assembly.LoadFrom работает раз через раз
Отправлено: vermesser от 29-12-2015, 22:20:57
Наводка: http://adn-cis.org/forum/index.php?topic=3062.0
Спасибо Вам большое, Вы мне очень помогли!
Название: Re: Assembly.LoadFrom работает раз через раз
Отправлено: Александр Ривилис от 29-12-2015, 22:22:47
Отлично. Если твой вопрос решился, то отметь наиболее подходящий ответ как Решение.