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

24/08/2013

Последовательность загрузки приложений в AutoCAD

Текст касается тех, кто значительно изменил / дополнил штатный функционал AutoCAD, и кого волнует последовательность загрузки собственных дополнений в AutoCAD. Вполне вероятно, что разъяснение загрузки, например, LISP-файлов, позволит выяснить причину некорректной их работы. В качестве примера здесь используется AutoCAD 2009, но подобные принципы используются во всех версиях AutoCAD начиная с 2006.

При старте AutoCAD прежде всего загружает свои CUI(X) файлы меню. Сначала загружается корпоративный файл меню (EnterpriseMenu), затем - основной файл меню (MainMenu), а затем - частичные меню (PartialMenu), присоединенные к основному, и в последнюю очередь - частичные файлы меню, присоединенные к корпоративному. Немного странная последовательность, но что есть то есть. Частичные файлы меню загружаются в той последовательности, в которой они были впервые загружены в AutoCAD. Обратите внимание - загружены, а не перечислены в команде _.menuload или _.cui. Этот порядок загрузки меню можно изменить. Самый простой способ - выгрузить частичные файлы меню и снова их загрузить в новом порядке. Можно, используя текстовые редакторы, вручную внести исправления в соответствующие CUI или CUIX файлы.

Рассмотрим подробнее механизм ручного изменения CUI/CUIX файлов. В качестве основных инструментов будем использовать текстовый редактор Notepad++ (распространяется бесплатно) и архиватор 7z (также бесплатен).
Для ручного внесения изменений в CUI-файл (используется в AutoCAD версии до 2009 включительно; при загрузке в последующие версии автоматически преобразовывается в CUIX) выполним такую последовательность действий:
Открытие cui в Notepad++ Откроем CUI файл в Notepad++
Установка форматирования Установим форматирование XML для удобства работы
Находим PartialMenuFile Найдем PartialMenuFile: ветка Header - CommonConfiguration
Меняем местами строки и сохраняем файл CUI. Может возникнуть желание удалить ненужные элементы, но я бы не советовал это делать: однажды подобным шагом я просто "убил" файл меню. Для редактирования CUIX-файла придется дополнительно выполнить несколько действий:
Открытие CUIX в 7z Открываем файл CUIX в 7z
Открытие CUI из-под 7z

Открытие CUI из-под 7z в Notepad++
Найдем файл Header.cui и вызовем контекстное меню.

Важно!

При выборе "Редактировать" файл Header.cui откроется в блокноте Windows. Вы сможете сразу выполнить редактирование и сохранить файл.
Но не забывайте, что в старых версиях Windows блокнот мог молча поменять кодировку файла с UTF-8 на ANSI-1251, что приводило к невозможности обработки такого файла. Поэтому лично я бы не рекомендовал подобный подход.
Можно "Открыть снаружи", отредактировать файл в текстовом редакторе, не меняющем без спроса кодировку файла, и потом положить отредактированный файл обратно в CUIX


Вернемся к последовательности загрузки.

Итак, AutoCAD загрузил свои CUI / CUIX файлы. Если в CUI / CUIX внедрены какие-либо LISP-файлы, то эти файлы в текущий момент еще не загружены.

Следом, если Вы создавали файл acad.rx и положили его в один из каталогов поиска AutoCAD, загружаются arx-модули, перечисленные в нем. Это один из путей автоматической загрузки arx-модулей.

После этого выполняется загрузка acad*.lsp-файлов. Сначала загружается acadXXXX.lsp, где XXXX - номер версии (для AutoCAD 2009 это будет файл acad2009.lsp, для AutoCAD 2013 - acad2013.lsp и т.п.). Если AutoCAD найдет файл acad.lsp, будет загружен этот файл. Меняя значение системной переменной ACADLSPASDOC, можно указать - либо файл acad.lsp будет грузиться только один раз в течение сессии, либо в каждый документ. В случае, если ACADLSPASDOC установлена в 1, то acad.lsp будет загружаться в каждый документ, следом за ним будет загружен файл acadXXXX.lsp, и / или acaddoc.lsp

Небольшое отступление: перечисленные файлы последовательно ищутся AutoCAD'ом сначала в каталоге с открываемым документом dwg, потом по всем каталогам поиска. Этим пользовались некоторые "вирусописатели" для AutoCAD, но в последних версиях Autodesk предприняла некоторые шаги по обеспечению безопасности своих пользователей.

Стоит особо отметить, что в принципе Вы можете дополнять / менять содержание этих файлов. Но Autodesk не рекомендует это делать: выход любого обновления может перезаписать эти файлы, и Вы потеряете все сделанные изменения.

Я очень давно не работал с VBA в AutoCAD, поэтому могу сказать только одно - если Вы создавали файл acad.dvb и положили его в один из путей поддержки AutoCAD, этот файл будет загружен. И загрузка будет выполнена именно сейчас.

Сейчас уже загружены все acad*.* файлы, пришло время загружать LISP-файлы, ассоциированные с меню. Если найден(ы) файлы MNL, лежащие рядом с файлом меню и имеющие такие же имена, выполняется их загрузка. Последовательно загрузки MNL такова же, какова и последовательность загрузки самих меню.

После MNL выполняется загрузка LISP, интегрированных в CUI / CUIX. Т.е. для любого меню сначала загружается MNL, потом внедренные в CUI / CUIX соответствующие LSP.

И только сейчас AutoCAD начинает опрашивать StartupSuite, загружая приложения оттуда в отображаемом порядке.

Фактически на данный момент загружены все модули и коды, но это еще не финал. Сейчас AutoCAD уже готов к выполнению команд и функций, вносящих изменения в базу чертежа. В принципе, есть неофициальные рекомендации выполнять подобные действия через специальную процедуру запуска, а не во время загрузки кодов. Но лично я этому не следую - пока нареканий не встречал.

Если у Вас есть в загрузке dvb-модуль, содержащий процедуру AcadStartup(), то эта функция начнет выполняться именно сейчас. При старте нового чертежа будет вызываться AcadDocument_Activate() вместо AcadStartup(). Но проверить это лично я не могу - опять же, не пишу на VBA.

Если в загрузку попали lsp-файлы, содержащие функцию (S::STARTUP), она автоматически выполняется. Для обеспечения полной корректности работы можно порекомендовать не полностью переопределять функцию (S::STARTUP), а дополнять ее код. В качестве примера можно привести такой код:

Код - Auto/Visual LISP: [Выделить]
  1. (defun my-loader () ;; Что-то делаем...
  2.  (princ (strcat "\nLoaded!.."))
  3. ) ;_ end of defun
  4. (setq s::startup
  5.  (if (and s::startup (listp s::startup))
  6.     (append s::startup my-loader)
  7.     my-loader
  8.  ) ;_ end of if
  9. ) ;_ end of setq


Фактически это повтор официальной документации.

Тем не менее есть еще как минимум одно решение, приведенное здесь:

Код - Auto/Visual LISP: [Выделить]
  1. (defun plug-into-startup (funcname) ;; by VladimirNesterovsky
  2. ;; "to be called with quoted function name"
  3.  (eval
  4.    (list 'defun 's::startup ()
  5.      (if s::startup (list (list 'quote s::startup)) ) ;_ end of if
  6.      (list funcname)
  7.    ) ;_ end of list
  8.  ) ;_ end of eval
  9. ) ;_ end of defun



К сожалению, вынужден сознаться, что пока проверить корректность работы что одного, что второго вариантов не могу: я пока не встречал ситуации, когда нужно было сохранять старый вариант s::startup, и я просто его переопределял...

Подведем итоги. Получается, что последовательность загрузки приложений в AutoCAD такова:
  1. Файлы меню (CUI / CUIX)
    • Корпоративное меню
    • Главное меню
    • Частичные меню, определенные в главном
    • Частичные меню, определенные в корпоративном
  2. Файлы acad*.*
    • acad.rx (определяет имена и последовательность загрузки arx)
    • acadXXXX.lsp
    • acad.lsp
    • acadXXXXdoc.lsp
    • acaddoc.lsp
    • acad.dvb
  3. Lisp-файлы, ассоццированные с файлами меню и / или внедренные в них
    • mnl-файл корпоративного меню
    • lsp, внедренный в корпоративное меню
    • mnl-файл основного меню
    • lsp, внедренный в основное меню
    • mnl-файлы, связанные с частичными меню, загруженными в основное
    • то же, но внедренные lsp
    • mnl-файлы, связанные с частичными меню, загруженными в корпоративное
    • то же, внедренные lsp
  4. StartupSuite (автозагрузка)
  5. Автоматически выполняемые функции и процедуры
    • AcadStartup() at AutoCAD startup
    • AcadDocument_Activate() at drawing startup
    • (s::startup)


Статья написана на основе материала
Автор: Алексей Кулик
Автор перевода: Алексей Кулик

Обсуждение: http://adn-cis.org/forum/index.php?topic=187

Опубликовано 24.08.2013