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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Автоматическая установка cui

Автоматическая установка cui

Ответ
Поиск в этой теме
Непрочитано 22.03.2011, 12:40 #1
Автоматическая установка cui
KuIZZInI
 
Регистрация: 09.12.2010
Сообщений: 10

Добрый день,
делаю инсталятор, подскажите что и куда необходимо поместить и прописать чтобы в автокад файл cui прописался автоматически, и отсутствовала необходимость прописывать его руками через "сервис->адаптация->интефейс".
Просмотров: 5837
 
Непрочитано 22.03.2011, 13:17
#2
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Application.MenuGroups.Load - но будь внимателен если в cui содержатся ссылки на внешние файлы (лиспы например), внутри cui'я никакие ссылки%ApplicationData% и пр. не работают - только прямые пути - я способа лучше чем непосредственно правка xml (делаю в 2008 - их более младшие (по возрасту) версии читают - дальше идут вобще "зазипованные") не нашел.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 22.03.2011, 13:31
#3
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от Дима_ Посмотреть сообщение
я способа лучше чем непосредственно правка xml (делаю в 2008 - их более младшие (по возрасту) версии читают - дальше идут вобще "зазипованные") не нашел.
У меня есть идея, как это обойти:
1. Считываем содержимое CUI-файла в обычную строковую переменную
2. Формируем словарь переменных, Dictionary<string,string>, в котором в качестве имени ключа - имя переменной, а в качестве значения - соответственно значение переменной.
3. Пробегаем по всем ключам в словаре из п.2, вызывая для каждого из них метод Replace на экземпляре string из п.1.
4. Теперь мы на руках имеем xml-файл, в котором все переменные заменены их значениями. Грузим в AutoCAD именно этот файл, а не изначальный CUI-файл.
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:
hwd вне форума  
 
Непрочитано 22.03.2011, 14:13
#4
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Я уж точно не помню почему - но если работать стандартными XML Noda'ми - там (cui) не все гладко - по факту у меня и реализованно примерно как ты пишешь:
Код:
[Выделить все]
File.WriteAllText(path+"my-panel.cui",File.ReadAllText(path+"my-panel.cui").Replace("***mypath***",path))
если мне понадобиться править несколько различных значений - "заверну" примерно как ты описал только не словарями а списками (на net я практически в 100% случаев пишу на F#).
p.s. "***mypath***" - я переправил в шаблоне в рукопашную, а path это Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData)+...
p.p.s - сейчас вспомнил - кроме шуток - когда я делал этот код (давно) у меня была мысль воспользоваться регексами.
__________________
Когда в руках молоток все вокруг кажется гвоздями.

Последний раз редактировалось Дима_, 22.03.2011 в 14:21.
Дима_ вне форума  
 
Непрочитано 22.03.2011, 14:22
#5
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от Дима_ Посмотреть сообщение
Я уж точно не помню почему - но если работать стандартными XML Noda'ми - там (cui) не все гладко
Не понял тебя. Проблем быть не должно, т.к. результат будет таким же, как если бы ты жёстко прописывал пути.
Цитата:
Сообщение от Дима_ Посмотреть сообщение
если мне понадобиться править несколько различных значений - "заверну" примерно как ты описал только не словарями а списками (на net я практически в 100% случаев пишу на F#).
Не важно на чём пишешь, если это .Net. Если под "списком" подразумевается List, то сие решение не есть гуд, т.к. не проверяется уникальность ключей.
Offtop: F# мне не интересен по ряду причин, а C# мне хватает за глаза для решения любых задач.

переменные бывают разные:
1.Переменные операционной системы:
1.1. переменные уровня локальной машины
1.2. переменные уровня процесса
1.3. переменные уровня юзера
2.Переменные приложения
При этом имена переменных не уникальны в общем пространстве. Например переменная Temp присутствует в 1.1, 1.2 и 1.3.
Переменная в своём значении может содержать имя др. переменной, т.о. нужно выполнить рекурсивную распаковку значения.
Код:
[Выделить все]
        /// <summary>
        /// Получить общий словарь, в котором собран набор переменных, определённых в общем конфигурационном файле настроек уровня домена, а так же в операционной системе на уровне всей локальной машины, на уровне текущего пользователя, на уровне текущего процесса. Имя каждого ключа содержит префикс, отделённый от основного имени точкой. Благодаря префиксу можно определить источник переменной: (SpecialFolder, Machine, User, Process, Xml, XmlPath). Префикс отделяется от имени переменной символом точка.
        /// </summary>
        /// <returns>Результат возвращается в виде словаря</returns>
        public Dictionary<string, string> GetVariables()
        {
            CheckAcadVersion();
            //Создаём временный словарь, в который будем сохранять промежуточный результат
            Dictionary<string, string> vars = new Dictionary<string, string>();
            Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            //Специальные каталоги Windows
            string[] names = Enum.GetNames(typeof(Environment.SpecialFolder));
            foreach (var item in names) {
                Environment.SpecialFolder sf = (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), item);
                vars.Add("SpecialFolder." + item, Environment.GetFolderPath(sf));
            }
            //Извлекаем значения всех системных переменных операционной системы
            EnvironmentVariableTarget et = EnvironmentVariableTarget.Machine;
            Environment.GetEnvironmentVariables(et).Keys.Cast<string>().All(n => { vars.Add("Machine." + n, Environment.GetEnvironmentVariable(n, et)); return true; });
            et = EnvironmentVariableTarget.User;
            Environment.GetEnvironmentVariables(et).Keys.Cast<string>().All(n => { vars.Add("User." + n, Environment.GetEnvironmentVariable(n, et)); return true; });
            et = EnvironmentVariableTarget.Process;
            Environment.GetEnvironmentVariables(et).Keys.Cast<string>().All(n => { vars.Add("Process." + n, Environment.GetEnvironmentVariable(n, et)); return true; });
            //Имя каталога конкретной версии продукта
            if (vars.ContainsKey("Xml.AcadVersion"))
                vars["Xml.AcadVersion"] = AcadVersion.Version;
            else
                vars.Add("Xml.AcadVersion", AcadVersion.Version);
            //Версия платформы
            if (vars.ContainsKey("Xml.Platform"))
                vars["Xml.Platform"] = AcadVersion.Platform.ToString();
            else
                vars.Add("Xml.Platform", AcadVersion.Platform.ToString());
            //Имя СИСТЕМЫ
            if (vars.ContainsKey("Xml.SystemName"))
                vars["Xml.SystemName"] = CommonSettings.SystemName;
            else
                vars.Add("Xml.SystemName", CommonSettings.SystemName);
            //Следующие две переменные явлются составляющими переменной Xml.AcadVersion, однако они нужны, т.к. используются в строке, на основании которой будет построено регулярное выражение
            //Старшая составляющая версии. Например для 17.2 это будет 17
            if (vars.ContainsKey("Xml.AcVerMajor"))
                vars["Xml.AcVerMajor"] = AcadVersion.Version.Split('.')[0];
            else
                vars.Add("Xml.AcVerMajor", AcadVersion.Version.Split('.')[0]);
            //Младшая составляющая версии. Например для 17.2 это будет 2
            if (vars.ContainsKey("Xml.AcVerMinor"))
                vars["Xml.AcVerMinor"] = AcadVersion.Version.Split('.')[0];
            else
                vars.Add("Xml.AcVerMinor", AcadVersion.Version.Split('.')[1]);

            //Теперь обрабатываем все имеющиеся записи
            foreach (var item in commonSettings.Directories)
            {
                vars.Add(item.Key, item.Value);
            }
            foreach (var item in commonSettings.OtherVariables)
            {
                foreach (var item2 in item.Value)
                {
                    vars.Add(item2.Key, item2.Value);
                }
            }
Рекурсивное извлечение выполняется с помощью такого метода:

Код:
[Выделить все]
        /// <summary>
        /// Получить значение переменной, рекурсивно заменив в нём присутствующие имена других переменных. В обрабатываемой строке имена переменных должны начинаться с символа '%' и заканчиваться им же. Переменные бывают уровня локальной машины, уровня пользователя, уровня процесса и уровня Системы.
        /// </summary>
        /// <param name="text">Строковое значение, подлежащее анализу</param>
        /// <param name="dict">Словарь содержащий в себе значения, на которые следует заменить имена переменных. Данный словарь следует получить с помощью метода GetVariables().</param>
        /// <returns>Возвращается строка, в которой имена всех переменных заменены на их значения</returns>
        public string ReplaceVarNames(string text, Dictionary<string, string> dict)
        {
            string data = text;
            string datapreview;
            do
            {
                datapreview = data;
                dict.All(n => { data = Regex.Replace(data, "%" + n.Key + "%", n.Value, RegexOptions.IgnoreCase); return true; });
            } while (data != datapreview);
            return data;
        }
Выше приведённый код - копипаст из моей рабочей софтины. Т.о. проверено на работоспособность.
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:

Последний раз редактировалось hwd, 24.03.2011 в 14:07. Причина: добавлен код
hwd вне форума  
 
Непрочитано 22.03.2011, 14:55
#6
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от hwd Посмотреть сообщение
переменные бывают разные:
не так быстро - это ты вобще к чему
з.ы. действительно только что ради интереса проверил замену через штатные api xml:
Код:
[Выделить все]
(xml.SelectSingleNode("CustSelection/MenuGroups/MenuRoot/LSPFile")).InnerText...
работает собака (и в акад прекрасно загружает) - видать чего-то тогда напортачил, ну и бог с ним.
з.з.ы - если под переменными ты о переменных окружения - то я знаю - %appdata% естественно для текущего юзера.
Offtop: По моему мы опять человеку всю тему засрали
__________________
Когда в руках молоток все вокруг кажется гвоздями.

Последний раз редактировалось Дима_, 22.03.2011 в 15:09.
Дима_ вне форума  
 
Непрочитано 22.03.2011, 15:04
#7
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от Дима_ Посмотреть сообщение
не так быстро - это ты вобще к чему
Я в первом фрагменте кода наглядно это показал - там всё подробно закомментировано пояснениями. Дабы различать переменные разных уровней - к имени каждой переменной программно добавляется префикс, с помощью которого можно легко определить, чья это переменная. Помимо этого, использование префикса устраняет неоднозначность (о которой я писал выше на примере переменной Temp) в именах переменных.
Префиксы, которые я использовал:
"Machine.", "Process.", "User.", "Xml." - последний из перечисленных соответствует уровню моего софта.

Цитата:
з.з.ы - если под переменными ты о переменных окружения - то я знаю - %appdata% естественно для текущего юзера.
и об этом в том числе.
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:

Последний раз редактировалось hwd, 22.03.2011 в 15:09.
hwd вне форума  
 
Непрочитано 23.03.2011, 08:45
#8
Frigate

КИП, АСУ ТП, слаботочка
 
Регистрация: 02.09.2010
Москва-Тюмень
Сообщений: 422


а может топик-стартеру достаточно будет всего лишь что-то типа такого кода:

Код:
[Выделить все]
(vl-load-com)

(setq sup_path (vla-get-supportpath (vla-get-files (vla-get-preferences (vlax-get-acad-object)))))

;|
(PRINC "\n")
(PRINC "Старые пути поддержки:")
(PRINC "\n")
(PRINC sup_path)
(PRINC "\n")
|;

(setq my_path ";C:\\ADV_CAD_AutoCAD;C:\\ADV_CAD_AutoCAD\\FUNCTIONS_DB;C:\\ADV_CAD_AutoCAD\\CUI")
(setq sup_path (strcat sup_path my_path))

(vla-put-supportpath (vla-get-files (vla-get-preferences (vlax-get-acad-object))) sup_path) 

;|
(PRINC "\n")
(PRINC "Новые пути поддержки:")
(PRINC "\n")
(PRINC (vla-get-supportpath (vla-get-files (vla-get-preferences (vlax-get-acad-object)))))
(PRINC "\n")
|;

(vl-cmdf "_.-WSSAVE" "" "_y")

(vl-cmdf "_.CUIUNLOAD" "adv_cad")
(vl-cmdf "_.CUILOAD" "adv_cad")

(setvar "WSCURRENT" (getvar "WSCURRENT"))

(PRINC "\nADV_CAD успешно загружен и настроен.")
вкратце - прописываем в пути поддержки папки нашего приложения, затем сохраняем текущее рабочее пространство, загружаем CUI, вновь подгружаем сохраненное рабочее пространство уже со всеми панельками инструментов, которые используются в нашем приложении. В таком варианте все наши настроенные панели инструментов остаются на своем месте.

Весь вышеуказанный код вставляем в ЛИСП файл и загружаем через _appload.

Думаю, несложно будет создать внешний exe, который запустит акад и автоматом сделает _appload. Но я пока в эту сторону не копал - не до этого пока.
Frigate вне форума  
 
Непрочитано 29.04.2011, 01:12
#9
stroygeodezia


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


А как хорошо и быстро было в 2012м. "Лепи" что душа пожелает, но аккуратно!!! И без всего этого "гемора".... Им-хо...
stroygeodezia вне форума  
 
Непрочитано 29.04.2011, 01:54
#10
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от Frigate Посмотреть сообщение
а может топик-стартеру достаточно будет всего лишь что-то типа такого кода:
Цитата:
Сообщение от stroygeodezia Посмотреть сообщение
А как хорошо и быстро было в 2012м. "Лепи" что душа пожелает, но аккуратно!!! И без всего этого "гемора"
Без гемора не получится, и кода из #8 не хватит... за n-цать лет автодеск не додумалась до того чтоб загружаемое меню появлялось автоматически... панельки появляются а меню нет...

Код:
[Выделить все]
 (defun c:cdl-setup ( / oldcmde menufile CNT)
  (vl-load-com)
  (setq oldcmde (getvar "CMDECHO"))
  (setvar "CMDECHO" 0)
  (if (menugroup "CADALYST")
	(progn
	  (prompt "\nВыгрузка текущего меню CADALYST. Подождите...")
	  (vl-cmdf "_menuunload" "CADALYST")
	)
  )
  (mapcar
  '(lambda(x / fn) (if (setq fn (findfile x)) (vl-file-delete fn)))
  '("_Cadalyst.cui" "_Cadalyst.mns" "_Cadalyst.mnc" "_Cadalyst.mnr")
  )
  (prompt "\nЗагрузка меню CADALYST. Подождите...")
  (cond
	((findfile (setq menufile "_Cadalyst.mnu"))
	  (vl-cmdf "_menuload" menufile)
	  (if (= "acad" (getvar "PROGRAM"))
		(progn
		  (setq CNT 1)
		  (while (< CNT 24)
			(if (menucmd (strcat "P" (itoa CNT) ".1=?"))
				(setq CNT (1+ CNT))
				(progn
				(if (> CNT 2)
					(setq CNT (- CNT 2))
					(setq CNT 2)
				)
				(menucmd (strcat "p" (itoa CNT) "=+CADALYST.pop1"))
				(setq CNT 25)
				)
			)
		  )
		  (setq CNT nil)
		)
	  )
	)
	(T (princ "\nНе возможно найти файл меню CADALYST!"))
  )
  (setvar "CMDECHO" oldcmde)
  (princ)
)
здесь не прописан поиск файла меню (каталога установки приложения)...

Последний раз редактировалось gomer, 29.04.2011 в 08:25.
gomer вне форума  
 
Непрочитано 29.04.2011, 02:07
#11
Кулик Алексей aka kpblc
Moderator

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


gomer, посмотри в справке MenuGroups - мне кажется, там были методы для загрузки и выгрузки меню.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 29.04.2011, 08:09
#12
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


gomer, когда цитаты лепишь - смотри кого автором назначаешь.
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:
hwd вне форума  
 
Непрочитано 29.04.2011, 08:29
#13
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


сорри исправил...

Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
посмотри в справке MenuGroups - мне кажется, там были методы для загрузки и выгрузки меню.
насколько мне известно, в акаде работают они аналогично командным методам и не намного быстрее, а вот в брикскаде меню загружается и доступно и происходит это пошустрее
gomer вне форума  
 
Непрочитано 29.04.2011, 08:37
#14
Лиспер


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


Код:
[Выделить все]
_$ (vlax-dump-Object (vla-get-MenuGroups (vlax-get-acad-object)) t)
; IAcadMenuGroups: A collection of MenuGroup objects representing all the menu groups loaded in the current AutoCAD session
; Property values:
;   Application (RO) = #<VLA-OBJECT IAcadApplication 0000000140637e28>
;   Count (RO) = 2
;   Parent (RO) = #<VLA-OBJECT IAcadApplication 0000000140637e28>
; Methods supported:
;   Item (1)
;   Load (2)
T
И дополнительно:
Код:
[Выделить все]
_$ (vlax-dump-Object (vla-item (vla-get-MenuGroups (vlax-get-acad-object)) 0) t)
; IAcadMenuGroup: An AutoCAD menu group
; Property values:
;   Application (RO) = #<VLA-OBJECT IAcadApplication 0000000140637e28>
;   MenuFileName (RO) = "C:\\Users\\lspr\\appdata\\roaming\\autodesk\\aca 2011\\enu\\support\\aca.cuix"
;   Menus (RO) = #<VLA-OBJECT IAcadPopupMenus 000000002c9be318>
;   Name (RO) = "ACA"
;   Parent (RO) = #<VLA-OBJECT IAcadMenuGroups 0000000007f6c510>
;   Toolbars (RO) = #<VLA-OBJECT IAcadToolbars 000000002c9be458>
;   Type (RO) = 0
; Methods supported:
;   Save (1)
;   SaveAs (2)
;   Unload ()
T
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 29.04.2011, 11:14
#15
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Кстати, раз уж вспомнили про методы - кто нибудь может сказать кому (чем) в автодеске метод Save помешал?
Цитата:
Сообщение от Лиспер Посмотреть сообщение
Methods supported:
; Save (1)
; SaveAs (2)
И цитата из справки
Цитата:
Menu groups cannot be saved in AutoCAD 2006 and later releases. This method will be removed from the MenuGroup object in a future release.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 29.04.2011, 16:43
#16
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515



для этого есть функция vl-file-copy
gomer вне форума  
 
Непрочитано 29.04.2011, 17:08
#17
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


А как ты ей сохранишь програмно созданнаю панель (эти методы кстати остались).
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 29.04.2011, 17:44
#18
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от Дима_ Посмотреть сообщение
А как ты ей сохранишь програмно созданнаю панель (эти методы кстати остались).
для конспирации это =) разве не понятно... создал, попользовался, уничтожил... динамика...
gomer вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Автоматическая установка cui



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Где найти xsd для cui файла? nav3000 AutoCAD 2 29.04.2011 01:23
Как убрать ненужные панели из ленты частичного CUI ??? Startrek AutoCAD 5 20.04.2010 01:20
Ищу РД 51-0220570-2-93 — Клапаны предохранительные. Выбор, установка и расчет rzinnurov Поиск литературы, чертежей, моделей и прочих материалов 0 21.05.2009 15:23
CUI – не могу адаптироваться. mmax AutoCAD 15 07.08.2007 10:11
Как пользовать Enterprize CUI ???????? Startrek AutoCAD 8 23.09.2005 17:23