| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > .NET Автоматизация netload во время отладки

.NET Автоматизация netload во время отладки

Ответ
Поиск в этой теме
Непрочитано 10.01.2012, 00:36 #1
.NET Автоматизация netload во время отладки
bargool
 
Санкт-Петербург
Регистрация: 16.08.2006
Сообщений: 508

Товарищи! Кто как преодолевает рутину частого netload во время отладки?
На TheSwamp мне подсказали вот такие 2 решения. scr-файл мне не подходит, т.к. на работе у меня SharpDevelop и 64-х битный AutoCAD (SharpDevelop не умеет запускать 64-х битные приложения для отладки), решение с lisp-файлом изящное. Насколько я понял, если в пути к открываемому dwg найдется bin\DEBUG - загружаются все dll-ки в папке?

Я же приведу свой вариант. Суть его такова: ставим сборку в автозагрузку автокада, она ждёт команды netload и запоминает то, что было загружено, в дальнейшем последнюю загруженную dll можно загрузить короткой командой ("an" в моём случае)
В папке со сборкой должен лежать файл appsettings.xml вида:
Код:
[Выделить все]
<?xml version="1.0" encoding="utf-8"?>
<Settings>
  <ProjectDirectory>C:\PROGGING\</ProjectDirectory>
</Settings>
где ProjectDirectory - путь до корневой папки для наших .net-проектов
Туда же в дальнейшем будет писаться путь до dll для использования при команде "an"
Класс инициализации приложения
Код:
[Выделить все]
 
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using acad = Autodesk.AutoCAD.ApplicationServices.Application;
 
namespace Bargool.Acad.AutoNetload
{
   /// <summary>
   /// Initialization of AutoNetload
   /// </summary>
   public class Initialization : IExtensionApplication
   {
      void IExtensionApplication.Initialize()
      {
         acad.DocumentManager.DocumentLockModeChanged
            += new DocumentLockModeChangedEventHandler(CommandClass.NetLoaded);
         // Reading path where our developing projects can found
         CommandClass.ReadProjectsPath();
      }
 
      void IExtensionApplication.Terminate()
      {
      }
   }
}
Собственно, основной рабочий класс
Код:
[Выделить все]
 using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml;
using System.Xml.Linq;
 
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using acad = Autodesk.AutoCAD.ApplicationServices.Application;
 
[assembly:CommandClass(typeof(Bargool.Acad.AutoNetload.CommandClass))]
 
namespace Bargool.Acad.AutoNetload
{
   /// <summary>
   /// There is routine to work with autonetloading
   /// </summary>
   public class CommandClass
   {
      static string projectsDir; // the root directory of all our developing projects
       
      /// <summary>
      /// Handler for event DocumentLockModeChanged
      /// </summary>
      public static void NetLoaded(object sender, DocumentLockModeChangedEventArgs e)
      {
         Document dwg = e.Document;
         if (e.GlobalCommandName.ToUpper() == "NETLOAD")
         {
            e.Veto();
            // Unregistering this handler
            acad.DocumentManager.DocumentLockModeChanged
               -= new DocumentLockModeChangedEventHandler(NetLoaded);
            // Register handler for AssemblyLoad event
            AppDomain.CurrentDomain.AssemblyLoad
               += new AssemblyLoadEventHandler(AppDomain_CurrentDomain_AssemblyLoad);
            dwg.SendStringToExecute("_netload\n", true, false, false);
         }
      }
       
      /// <summary>
      /// Method getting assembly path from appsettings.xml and loading it
      /// </summary>
      [CommandMethod("an")]
      public void RestoreNetLoad()
      {
         try
         {
            // Getting appsettings.xml
            XDocument cfg = GetAppsettings();
            // Getting assembly from previous netload
            string assemblyToLoadPath = cfg.Descendants("AssemblyPath").First().Value;
            // If AssemblyPath in cfg is proper - loading it
            if (assemblyToLoadPath.ToUpper().StartsWith(projectsDir))
            {
		Assembly.LoadFrom(assemblyToLoadPath);
               acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
                  "\nAssembly {0} loaded", assemblyToLoadPath);
            }
            else
            {
               string s = "\nError in appsettings.xml\nCorrect it:\n"+
                  "AssemblyPath have to start with ProjectDirectory there";
               acad.ShowAlertDialog(s);
            }
         }
         catch (XmlException xmlex)
         {
            acad.ShowAlertDialog(
               String.Format(
                  "\nError while loading appsettings.xml:\n{0}",
                  xmlex.Message));
         }
         catch (IOException ioex)
         {
            acad.ShowAlertDialog(
               String.Format(
                  "\nError while loading assembly:\n{0}",
                  ioex.Message));
         }
         catch (System.Exception ex)
         {
            acad.ShowAlertDialog(
               String.Format("\nError:\n{0}", ex.Message));
         }
      }
       
      /// <summary>
      /// Handler for AssemblyLoad event
      /// </summary>
      static void AppDomain_CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
      {
         // If loaded assembly in our projects dir, writing it to appsettings.xml
         if (args.LoadedAssembly.Location.ToUpper().StartsWith(projectsDir))
         {
            // Unregistering from AssemblyLoad event
            AppDomain.CurrentDomain.AssemblyLoad -=
               new AssemblyLoadEventHandler(AppDomain_CurrentDomain_AssemblyLoad);
            WriteLoadedAssembly(args.LoadedAssembly.Location);
         }
      }
       
      /// <summary>
      /// Writing appsettings.xml with path to AssemblyPath node
      /// </summary>
      /// <param name="path">path to write to AssemblyPath node</param>
      static void WriteLoadedAssembly(string path)
      {
         // Getting current assembly directory
         string assemblyPath =
            Path.GetDirectoryName(
               Assembly.GetAssembly(new CommandClass().GetType())
               .Location);
         try
         {
            XDocument appsettings =
               new XDocument(
                  new XElement("Settings",
                               new XElement("ProjectDirectory", projectsDir),
                               new XElement("AssemblyPath", path)));
            appsettings.Save(Path.Combine(assemblyPath, "appsettings.xml"));
         }
         catch (XmlException xmlex)
         {
            acad.ShowAlertDialog(
               String.Format(
                  "\nError while writing appsettings.xml:\n{0}", xmlex.Message));
         }
         catch (System.Exception ex)
         {
            acad.ShowAlertDialog(
               String.Format("\nError:\n{0}", ex.Message));
         }
      }
       
      /// <summary>
      /// Reading directory where our developing projects have to be
      /// </summary>
      public static void ReadProjectsPath()
      {
         XDocument cfg = GetAppsettings();
         try
         {
            projectsDir = cfg.Descendants("ProjectDirectory").First().Value.ToUpper();
         }
         catch (XmlException xmlex)
         {
            acad.ShowAlertDialog(
               String.Format(
                  "\nError while reading ProjectDirectory from appsettings.xml:\n{0}",
                  xmlex.Message));
         }
      }
       
      /// <summary>
      /// Getting XML document with setting for app
      /// </summary>
      /// <returns>XML document with setting for app</returns>
      static XDocument GetAppsettings()
      {
         string assemblyPath =
            Path.GetDirectoryName(
               Assembly.GetAssembly(new CommandClass().GetType())
               .Location);
         XDocument cfg = null;
         try
         {
            cfg = XDocument.Load(Path.Combine(assemblyPath, "appsettings.xml"));
         }
         catch (System.Exception ex)
         {
            acad.ShowAlertDialog(
               String.Format("\nError:\n{0}", ex.Message));
         }
         return cfg;
      }
   }
}
Просьба прокомментировать тот вариант с lisp-ом (правильно ли я его понял), ну и жду критику по моему решению..

Последний раз редактировалось bargool, 11.01.2012 в 13:24.
Просмотров: 9107
 
Автор темы   Непрочитано 11.01.2012, 13:25
#2
bargool


 
Регистрация: 16.08.2006
Санкт-Петербург
Сообщений: 508
<phrase 1=


Обновил пост - нашел ошибку в коде: заменил
Код:
[Выделить все]
 Assembly asm = Assembly.LoadFile(assemblyToLoadPath);
AppDomain.CurrentDomain.Load(asm.GetName());
на
Код:
[Выделить все]
 Assembly.LoadFrom(assemblyToLoadPath);
т.к. при использовании в вашем приложении дополнительных сборок, которые до этого не были загружены в Автокад, он их не находил
bargool вне форума  
 
Непрочитано 12.01.2012, 12:26
#3
xsakabsx


 
Регистрация: 18.04.2010
Сообщений: 46


Зачем так много писать если можно через acad.lsp грузить ,

там и кода меньше будет да и всегда можно закоментить ?
xsakabsx вне форума  
 
Автор темы   Непрочитано 12.01.2012, 14:08
#4
bargool


 
Регистрация: 16.08.2006
Санкт-Петербург
Сообщений: 508
<phrase 1=


xsakabsx, причин несколько:
  • я не только программирую, и автокад без всяких глючащих сборок может понадобиться в любой момент
  • я лентяй, и не хочу помнить, нужно мне что-то удалять из acad.lsp или нет
  • опять же, лезть каждый раз добавлять туда сборку тоже лень
  • а если я сделал тестовый проект, который проживет 2 часа, опять туда дописывать, а потом удалять (или комментить)?
  • а если надо с одного проекта переключиться на другой на те же 2 часа?
  • просто интересно (это наверное самое главное ), и в конце концов - этот проект я могу в дальнейшем использовать в других целях
  • можно ещё что-нибудь напридумывать
Естественно, эти причины важны только для меня. А так вариантов куча: можно и в acad.lsp писать, можно сделать mnu-файл куда дописывать то же самое, можно в реестр писать автозагрузку сборок.
bargool вне форума  
 
Непрочитано 13.04.2018, 12:38
#5
Krapivnik


 
Регистрация: 04.11.2008
Город П
Сообщений: 616


Цитата:
Сообщение от bargool Посмотреть сообщение
Насколько я понял, если в пути к открываемому dwg найдется bin\DEBUG - загружаются все dll-ки в папке?
Решение неплохое, но сссылка ведёт к нерабочему коду. Условие
Код:
[Выделить все]
 (if (wcmatch (strcase path) "*bin\\DEBUG*")
никогда не будет выполнено, т.к. переменная "path" содержит путь к файлу чертежа, открутому на две папки выше, чем лежит DLL-плагин. Соответственно, "path" никогда не будет содержать в себе строку "*bin\\DEBUG*".
Для тех кто будет пользоваться этим способом можно упростить код, убрав лишние условия. DLL положить рядом с запускаемым DWG-файлом. Это довольно удобно при отладке.
Следующий код необходимо внести в файл c:\program files\autodesk\autocad 20xx\support\acad20xxdoc.lsp
Автоматический запуск команды netload с автозагрузкой всех dll-плагинов из директории чертежа:
Код:
[Выделить все]
 ;; Автоматический запуск команды netload с автозагрузкой всех dll-плагинов из директории чертежа
(princ "\nПОИСК DLL-ПЛАГИНА В ПАПКЕ С ЧЕРТЕЖОМ")
(defun DebugNET (/ path fn)
  (setq path (getvar "DWGPREFIX"))
     (foreach fn (vl-directory-files path "*.DLL" 1)
        (command "._NetLoad" fn)
    )
    (princ)
)
(DebugNET)
Есть еще одна тонкость: если ваш плагин предполагает работу с интрерфейсом Ribbon (с лентой), то он иожет не загрузиться, т.к. Автокад в некоторых версиях загружает ленту после исполнения кода из файла acad20xxdoc.lsp. Для этой цели возможно передать команду _Ribbon до вызова функции DebugNET (загрузить ленту перед исполнением netload):

Код:
[Выделить все]
 ;; Автоматический запуск команды netload с автозагрузкой всех dll-плагинов из директории чертежа с предварительной загрузкой ленты
(princ "\nПОИСК DLL-ПЛАГИНА В ПАПКЕ С ЧЕРТЕЖОМ")
(defun DebugNET (/ path fn)
  (setq path (getvar "DWGPREFIX"))
     (foreach fn (vl-directory-files path "*.DLL" 1)
        (command "._NetLoad" fn)
    )
    (princ)
)
(command "_RIBBON")
(DebugNET)
Krapivnik вне форума  
 
Непрочитано 13.04.2018, 12:51
#6
Boxa

КЖ; C#
 
Регистрация: 03.11.2005
Санкт-Петербург
Сообщений: 2,588


Чего то Вы мудрите...
Ведь куда проще в папке автозагрузки плагинов создать отладочный bundle пакет и директорию непосредственно с dll подцепить хард линком внутрь этого пакета и все будет загружаться само.
Boxa вне форума  
 
Непрочитано 13.04.2018, 12:59
#7
Krapivnik


 
Регистрация: 04.11.2008
Город П
Сообщений: 616


Цитата:
Сообщение от Boxa Посмотреть сообщение
Чего то Вы мудрите...
Ведь куда проще в папке автозагрузки плагинов создать отладочный bundle пакет и директорию непосредственно с dll подцепить хард линком внутрь этого пакета и все будет загружаться само.
Если честно, я не понял удобства
Может напишите подробнее процедуру работы в этом случае?
Krapivnik вне форума  
 
Непрочитано 15.04.2018, 07:02
#8
Boxa

КЖ; C#
 
Регистрация: 03.11.2005
Санкт-Петербург
Сообщений: 2,588


удобство в том, что не нужно писать никакие программы автозагрузки, автокад все делает сам.
Boxa вне форума  
 
Непрочитано 15.04.2018, 20:16
#9
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


ИМХО там же и проблема - приложения, прописанные подобным образом, грузятся во все профили ACAD (если я правильно понимаю, конечно). В некоторых случаях подобное не совсем выгодно.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 15.04.2018, 20:57
#10
Boxa

КЖ; C#
 
Регистрация: 03.11.2005
Санкт-Петербург
Сообщений: 2,588


Кулик Алексей aka kpblc, ну при отладке это скорее плюс, возможность отработать грабли и баги во всех профилях...
Boxa вне форума  
 
Непрочитано 16.04.2018, 07:00
#11
Krapivnik


 
Регистрация: 04.11.2008
Город П
Сообщений: 616


Цитата:
Сообщение от Boxa Посмотреть сообщение
удобство в том, что не нужно писать никакие программы автозагрузки, автокад все делает сам.
Цитата:
Сообщение от Boxa Посмотреть сообщение
куда проще в папке автозагрузки плагинов
Как задать папку автозагрузки .NET плагинов? У меня AutoCAD2011.


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
ИМХО там же и проблема - приложения, прописанные подобным образом, грузятся во все профили ACAD (если я правильно понимаю, конечно). В некоторых случаях подобное не совсем выгодно.
Первый способ с автозагрузкой из папки с чертежом для отладочных целей - самое то. Пусть грузятся.
Krapivnik вне форума  
 
Непрочитано 16.04.2018, 10:28
#12
Boxa

КЖ; C#
 
Регистрация: 03.11.2005
Санкт-Петербург
Сообщений: 2,588


Цитата:
Сообщение от Krapivnik Посмотреть сообщение
У меня AutoCAD2011.
С такой вводной - никак. Вам остается пользоваться костылями из лиспа. Автодеск сделал автозагрузку для bundle пакетов с 2012 версии. Увы.
Boxa вне форума  
 
Непрочитано 16.04.2018, 13:53
#13
Do$

AutoCAD/Civil3D LISP/C#
 
Регистрация: 15.08.2008
Санкт-Петербург
Сообщений: 1,702
Отправить сообщение для Do$ с помощью Skype™


Цитата:
Сообщение от bargool Посмотреть сообщение
Товарищи! Кто как преодолевает рутину частого netload во время отладки?
Мне кажется, что не так уж сложно сложно набрать NETLOAD и указать путь к DLL, разве нет?
Цитата:
Сообщение от bargool Посмотреть сообщение
она ждёт команды netload и запоминает то, что было загружено, в дальнейшем последнюю загруженную dll можно загрузить короткой командой ("an" в моём случае)
Так ведь AutoCAD сам запоминает последний путь загрузки. То есть, два действия: NETLOAD и кликнуть по нужной DLL 2 раза. На фоне времени загрузки AutoCAD и открытия нужного чертежа - это капля в море.

P.S. Ой, не посмотрел на время создания темы и автора Ну ладно, пусть будет...
__________________
Толковый выбор приходит с опытом, а к нему приводит выбор бестолковый. (The Mechanic)

Последний раз редактировалось Do$, 16.04.2018 в 14:00.
Do$ вне форума  
 
Автор темы   Непрочитано 22.04.2018, 23:45
#14
bargool


 
Регистрация: 16.08.2006
Санкт-Петербург
Сообщений: 508
<phrase 1=


Да, ребят. Теме уже 6 лет, я уже 2 года не видел автокад )))
В #4 сообщении я довольно точно описал свою мотивацию на тот момент.
Могу сказать, что я несколько лет успешно пользовался этим кодом для оперативной загрузки разрабатываемых плагинов. Этож сколько нажатий клавиш и времени оно мне сэкономило...
__________________
Алексей
bargool вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > .NET Автоматизация netload во время отладки

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
А как насчёт уважения к РУССКОМУ ЯЗЫКУ, дамы и господа инженеры? Зяблик Разное 1249 17.02.2023 16:20
Личное огнестрельное оружие в Европе и США PL Разное 2335 01.05.2012 18:18
Ночное время -это от сколько и доскольки (как считать)? sbi Разное 8 09.11.2011 10:10
ВРЕМЯ Vova Разное 29 08.03.2009 10:40
Юмор 2007 Огурец Разное 1172 29.12.2007 11:16