Получить путь к acdbmgd.dll в NET без Interop

Автор Тема: Получить путь к acdbmgd.dll в NET без Interop  (Прочитано 11252 раз)

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

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1189
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Суть данной проблемы получить полное имя сборки acdbmgd.dll (для версий AutoCAD 2006 -2015).
Если предположить, что файл acdbmgd.dll всегда находится в корне acad.exe. То нужно получить путь к acad.exe.
В COM получить путь не проблема Interop.AcadApplication.path, а как получить путь работая только в
NET без подключения сборки Interop?

Я нашел только,
HostApplicationServices.Current.RoamableRootFolder
HostApplicationServices.Current.LocalRootFolder
но это не то, может потом будет где-то полезно.
« Последнее редактирование: 26-12-2014, 13:22:36 от Александр Ривилис »

Отмечено как Решение Александр Ривилис 25-12-2014, 03:25:32

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить путь к acad.exe в NET без Interop
« Ответ #1 : 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. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1189
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Получить путь к acad.exe в NET без Interop
« Ответ #2 : 25-12-2014, 03:23:16 »
Спасибо, такой вариант решения вполне подойдет!

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Получить путь к acad.exe в NET без Interop
« Ответ #3 : 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
« Последнее редактирование: 25-12-2014, 10:55:08 от Андрей Бушман »

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Получить путь к acad.exe в NET без Interop
« Ответ #4 : 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

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить путь к acad.exe в NET без Interop
« Ответ #5 : 25-12-2014, 11:37:24 »
Если второй вариант, то я предпочитаю не полагаться на то совпадение, о котором ты упоминаешь.
Тогда ты полагаешься на то, что реестр никто не правил ручками (это я про твой следующий код).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Получить путь к acad.exe в NET без Interop
« Ответ #6 : 25-12-2014, 11:39:49 »
Тогда ты полагаешься на то, что реестр никто не правил ручками (это я про твой следующий код).
Поскольку автодеск хранит эту информацию в реестре, то существует вероятность, что какой-то софт того же автодеска может этой информацией пользоваться и в случае изменения её "ручками" накроется медным тазом. Я исхожу из того, что это официальная информация, предоставляемая автодеском и здравомыслящий человек не будет править её в HKLM. Более того, в нормальных организациях юзеры не имеют прав админа.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить путь к acad.exe в NET без Interop
« Ответ #7 : 25-12-2014, 11:55:12 »
Андрей Бушман. Всё тоже самое можно повторить о расположении acdbmgd.dll и acad.exe.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1189
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Получить путь к acdbmgd.dll в NET без Interop
« Ответ #8 : 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"
что-то у меня не получается.
« Последнее редактирование: 25-12-2014, 22:00:35 от Алексей (IdeaSoft) »

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Получить путь к acad.exe в NET без Interop
« Ответ #9 : 25-12-2014, 22:04:49 »
Т.к. acdbmgd.dll должен быть там где и acad.exe, то достаточно получить путь к acad.exe.
Я выше показал, как получить путь к acdbmgd.dll.
Я пробовал класть acdbmgd.dll в другую папку класс не создается возникают ошибки,
так что правильнее, если они (dll и exe) буду в одной папке.
У Autodesk они не поменяют своего места расположения с вероятностью 99,9%. Можно переложить их в др. каталог и всё будет работать при условии, что ты возьмёшь в свои руки поиск нужных ресурсов путём подписания на соответствующее событие. Я так нередко делаю, когда выношу свои общие библиотеки в некоторый каталог, дабы не дублировать их в каждом плагине.

Оффлайн JohnJ

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
Re: Получить путь к acad.exe в NET без Interop
« Ответ #10 : 26-12-2014, 08:13:57 »
Это потому из-за того, что подключив к моему проекту сборки acad 2006 компилятор не находит класс MLeader.
А не проще ли тогда воспользоваться условиями компиляции и исключать с помощью них код для версий, в которых он не должен работать?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить путь к acdbmgd.dll в NET без Interop
« Ответ #11 : 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.  
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Получить путь к acdbmgd.dll в NET без Interop
« Ответ #12 : 26-12-2014, 14:04:56 »
Type.GetType("Autodesk.AutoCAD.DatabaseServices.MLeader");
тогда уж так:
Код - C# [Выбрать]
  1. Type.GetType("Autodesk.AutoCAD.DatabaseServices.MLeader", false, true);
безо всяких try\catch.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить путь к acdbmgd.dll в NET без Interop
« Ответ #13 : 26-12-2014, 14:09:22 »
тогда уж так:
Код - C#: [Выделить]

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

безо всяких try\catch.
Не могу проверить был ли этот метод в .NET 1.1 и 2.0
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение