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

ADN Club => AutoCAD .NET API => Тема начата: Алексей (IdeaSoft) от 25-12-2014, 02:10:06

Название: Получить путь к acdbmgd.dll в NET без Interop
Отправлено: Алексей (IdeaSoft) от 25-12-2014, 02:10:06
Суть данной проблемы получить полное имя сборки acdbmgd.dll (для версий AutoCAD 2006 -2015).
Если предположить, что файл acdbmgd.dll всегда находится в корне acad.exe. То нужно получить путь к acad.exe.
В COM получить путь не проблема Interop.AcadApplication.path, а как получить путь работая только в
NET без подключения сборки Interop?

Я нашел только,
HostApplicationServices.Current.RoamableRootFolder
HostApplicationServices.Current.LocalRootFolder
но это не то, может потом будет где-то полезно.
Название: Re: Получить путь к acad.exe в NET без Interop
Отправлено: Александр Ривилис от 25-12-2014, 02:29:50
(в acad 2013 Interop же нет)  ?
Эту фразу я не понял категорически.  Вот так можно получить путь к acad.exe (это один из множества вариантов)
Код - C# [Выбрать]
  1. [CommandMethod("PathExe")]
  2. public void PathExe()
  3. {
  4.       Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  5.       string path = System.Windows.Forms.Application.ExecutablePath;
  6.       ed.WriteMessage("\nPath={0}",path);
  7. }
Название: Re: Получить путь к acad.exe в NET без Interop
Отправлено: Алексей (IdeaSoft) от 25-12-2014, 03:23:16
Спасибо, такой вариант решения вполне подойдет!
Название: Re: Получить путь к acad.exe в NET без Interop
Отправлено: Андрей Бушман от 25-12-2014, 10:32:30
Если предположить, что файл acdbmgd.dll всегда находится в корне acad.exe. То нужно получить путь к acad.exe.
Ты определись, тебе нужно получить путь к acad.exe (как ты пишешь в названии темы), или же тебе нужно получить полное имя файла acdbmgd.dll (как ты пишешь в первом сообщении темы)? Это "четыре совершенно разных человека".

Если второй вариант, то я предпочитаю не полагаться на то совпадение, о котором ты упоминаешь.
Код - C# [Выбрать]
  1. String acdbmgd_fullPath = typeof(Db.Database).Assembly.Location;
Результат:
Цитировать
C:\Program Files\Autodesk\AutoCAD 2009\AcdbMgd.dll
Название: Re: Получить путь к acad.exe в NET без Interop
Отправлено: Андрей Бушман от 25-12-2014, 10:52:52
А если всё же нужно путь к acad.exe, то
Код - C# [Выбрать]
  1. String acad_fullName = null;
  2.  
  3. String rkName = Db.HostApplicationServices.Current
  4.     .RegistryProductRootKey;
  5. using (RegistryKey reg = Registry.LocalMachine.OpenSubKey(rkName,
  6.     false)) {
  7.     acad_fullName = reg.GetValue("AcadLocation").ToString();
  8.     reg.Close();
  9. }
Результат:
Цитировать
C:\Program Files\Autodesk\AutoCAD 2009
Название: Re: Получить путь к acad.exe в NET без Interop
Отправлено: Александр Ривилис от 25-12-2014, 11:37:24
Если второй вариант, то я предпочитаю не полагаться на то совпадение, о котором ты упоминаешь.
Тогда ты полагаешься на то, что реестр никто не правил ручками (это я про твой следующий код).
Название: Re: Получить путь к acad.exe в NET без Interop
Отправлено: Андрей Бушман от 25-12-2014, 11:39:49
Тогда ты полагаешься на то, что реестр никто не правил ручками (это я про твой следующий код).
Поскольку автодеск хранит эту информацию в реестре, то существует вероятность, что какой-то софт того же автодеска может этой информацией пользоваться и в случае изменения её "ручками" накроется медным тазом. Я исхожу из того, что это официальная информация, предоставляемая автодеском и здравомыслящий человек не будет править её в HKLM. Более того, в нормальных организациях юзеры не имеют прав админа.
Название: Re: Получить путь к acad.exe в NET без Interop
Отправлено: Александр Ривилис от 25-12-2014, 11:55:12
Андрей Бушман. Всё тоже самое можно повторить о расположении acdbmgd.dll и acad.exe.
Название: Получить путь к acdbmgd.dll в NET без Interop
Отправлено: Алексей (IdeaSoft) от 25-12-2014, 21:40:04
Мне нужно получить полный путь acdbmgd.dll, что бы через отражение я создал экземпляр класса MLeader,
которого нет в AutoCAD 2006 и 2007.
Это потому из-за того, что подключив к моему проекту сборки acad 2006 компилятор не находит класс MLeader.
Я не хочу комментировать каждый раз код, когда делаю сборку своего проекта для acad 2006, 2007.
Класс MLeader в acad 2007,2006 работать не будет, просто мой алгоритм проигнорирует создание класса MLeader и все.
Использовав позднее связывание мне не нужно комментировать кусок кода.

Т.к. acdbmgd.dll должен быть там где и acad.exe, то достаточно получить путь к acad.exe.
Я пробовал класть acdbmgd.dll в другую папку класс не создается возникают ошибки,
так что правильнее, если они (dll и exe) буду в одной папке. 

Вот пример кода:

Код - Visual Basic [Выбрать]
  1. Public Sub TEST
  2.        Dim path As String = sys_GetPath_FullName(System.Windows.Forms.Application.ExecutablePath)
  3.        Dim DllName As String = path & "\acdbmgd.dll"
  4.        Dim leader As Object = Create_Inst_ClassName(DllName, "Autodesk.AutoCAD.DatabaseServices.MLeader")
  5.       ' делаю проверку, если экземпляр класса не создан
  6.      If leader Is Nothing Then Exit Sub
  7. End Sub
  8. ' создание экземпляра класса по имени из файла dllFile
  9. Public Function Create_Inst_ClassName(ByVal dllFile As String, _
  10.           ByVal ClassName As String) As Object
  11.         Try
  12.             With System.Reflection.Assembly.LoadFrom(dllFile)
  13.                 Dim obj As Object = Activator.CreateInstance(.GetType(ClassName))
  14.                 Return obj
  15.             End With
  16.         Catch ex As Exception
  17.             Return Nothing
  18.         End Try
  19. End Function
  20.  
  21. ' папка от полного имени файла
  22. Public Shared Function sys_GetPath_FullName(ByVal FullName As String) As String
  23.         Dim strAppPath As String = FullName
  24.         Dim i As Long = strAppPath.Length - 1
  25.         Do Until strAppPath.Substring(i, 1) = "\"
  26.             i -= 1
  27.         Loop
  28.         strAppPath = strAppPath.Substring(0, i)
  29.         Return strAppPath
  30. End Function
  31.  
Саша, поменяй пожалуйста название темы на "Получить путь к acdbmgd.dll в NET без Interop"
что-то у меня не получается.
Название: Re: Получить путь к acad.exe в NET без Interop
Отправлено: Андрей Бушман от 25-12-2014, 22:04:49
Т.к. acdbmgd.dll должен быть там где и acad.exe, то достаточно получить путь к acad.exe.
Я выше показал, как получить путь к acdbmgd.dll.
Я пробовал класть acdbmgd.dll в другую папку класс не создается возникают ошибки,
так что правильнее, если они (dll и exe) буду в одной папке.
У Autodesk они не поменяют своего места расположения с вероятностью 99,9%. Можно переложить их в др. каталог и всё будет работать при условии, что ты возьмёшь в свои руки поиск нужных ресурсов путём подписания на соответствующее событие. Я так нередко делаю, когда выношу свои общие библиотеки в некоторый каталог, дабы не дублировать их в каждом плагине.
Название: Re: Получить путь к acad.exe в NET без Interop
Отправлено: JohnJ от 26-12-2014, 08:13:57
Это потому из-за того, что подключив к моему проекту сборки acad 2006 компилятор не находит класс MLeader.
А не проще ли тогда воспользоваться условиями компиляции и исключать с помощью них код для версий, в которых он не должен работать?
Название: Re: Получить путь к acdbmgd.dll в NET без Interop
Отправлено: Александр Ривилис от 26-12-2014, 14:01:07
Алексей (IdeaSoft), мне кажется что ты перемудрил. Если твоё .NET приложение загружено, то и acdbmgd.dll уже загружено в AutoCAD. Достаточно проверить:
Код - C# [Выбрать]
  1.     public bool HasMLeaderClass()
  2.     {
  3.       try
  4.       {
  5.         Type.GetType("Autodesk.AutoCAD.DatabaseServices.MLeader");
  6.         return true;
  7.       }
  8.       catch
  9.       {
  10.         return false;
  11.       }
  12.     }
  13.     [CommandMethod("MLE")]
  14.     public void mle()
  15.     {
  16.       Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  17.       string path = System.Windows.Forms.Application.ExecutablePath;
  18.       ed.WriteMessage("\nКласс MLeader {0}определён.",
  19.         HasMLeaderClass() ? "" : "не");
  20.     }
  21.  
Название: Re: Получить путь к acdbmgd.dll в NET без Interop
Отправлено: Андрей Бушман от 26-12-2014, 14:04:56
Type.GetType("Autodesk.AutoCAD.DatabaseServices.MLeader");
тогда уж так:
Код - C# [Выбрать]
  1. Type.GetType("Autodesk.AutoCAD.DatabaseServices.MLeader", false, true);
безо всяких try\catch.
Название: Re: Получить путь к acdbmgd.dll в NET без Interop
Отправлено: Александр Ривилис от 26-12-2014, 14:09:22
тогда уж так:
Код - C#: [Выделить]

    Type.GetType("Autodesk.AutoCAD.DatabaseServices.MLeader", false, true);

безо всяких try\catch.
Не могу проверить был ли этот метод в .NET 1.1 и 2.0