Каждому профилю AutoCAD – свой файл меню!
Откровенно говоря, меня "достала" ситуация, когда основной файл меню в каждом профиле AutoCAD один и тот же. Мне необходимо иметь в каждом профиле AutoCAD свой файл меню, который не будет ни с кем конфликтовать. Конечно, хочется как-то решить это дело быстро и безболезненно.
Попробуем сделать таким образом: для каждого профиля AutoCAD создадим свою копию файла acad.cuix (естественно, что для вертикальных приложений название основного файла меню будет другим), назначим его как основной и внесем путь к этому файлу в список путей поддержки. Ну так, чтобы уж с гарантией.
В результате вечерних посиделок появилось такое чудо:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | (vl-load-com) (defun c:menuseparate (/ get-all-reg-hives _kpblc-conv-string-to-list _kpblc-dir-create _kpblc-get-profile-name hive) ;| * Проходит по всем профилям всех версий и локализаций AutoCAD. * Переносит основной файл меню в отдельный каталог * %appdata%\Autodesk\<AppName>\<rus|enu>\Support\Profiles\<ProfileName> * и добавляет этот каталог в путь поддержки AutoCAD, в самое начало. * Критерием необходимости переноса является то, что в пути к основному файлу меню * отсутствует имя профиля. Перед этим имя профиля преобразовывается - из него исключаются символы, * недопустимые в именах файлов Windows |; (defun get-all-reg-hives (parent) (cond ((and (vl-registry-descendents parent) (member "PROFILES" (mapcar (function strcase) (vl-registry-descendents parent))) ) ;_ end of and (mapcar (function (lambda (x) (strcat parent "\\Profiles\\" x) ) ;_ end of lambda ) ;_ end of function (vl-registry-descendents (strcat parent "\\Profiles")) ) ;_ end of mapcar ) ((vl-registry-descendents parent) (apply (function append) (mapcar (function (lambda (x) (get-all-reg-hives (strcat parent "\\" x)) ) ;_ end of lambda ) ;_ end of function (vl-registry-descendents parent) ) ;_ end of mapcar ) ;_ end of apply ) ) ;_ end of cond ) ;_ end of defun (defun _kpblc-conv-string-to-list (string separator / i) (cond ((= string "") nil) ((vl-string-search separator string) ((lambda (/ pos res) (while (setq pos (vl-string-search separator string)) (setq res (cons (substr string 1 pos) res) string (substr string (+ (strlen separator) 1 pos)) ) ;_ end of setq ) ;_ end of while (reverse (cons string res)) ) ;_ end of lambda ) ) ((wcmatch (strcase string) (strcat "*" (strcase separator) "*")) ((lambda (/ pos res _str prev) (setq pos 1 prev 1 _str (substr string pos) ) ;_ end of setq (while (<= pos (1+ (- (strlen string) (strlen separator)))) (if (wcmatch (strcase (substr string pos (strlen separator))) (strcase separator)) (setq res (cons (substr string 1 (1- pos)) res) string (substr string (+ (strlen separator) pos)) pos 0 ) ;_ end of setq ) ;_ end of if (setq pos (1+ pos)) ) ;_ end of while (if (< (strlen string) (strlen separator)) (setq res (cons string res)) ) ;_ end of if (if (or (not res) (= _str string)) (setq res (list string)) (reverse res) ) ;_ end of if ) ;_ end of lambda ) ) (t (list string)) ) ;_ end of cond ) ;_ end of defun (defun _kpblc-dir-create (path / tmp) (cond ((vl-file-directory-p path) path) ((setq tmp (_kpblc-dir-create (vl-filename-directory path))) (vl-mkdir (strcat tmp "\\" (vl-filename-base path) (cond ((vl-filename-extension path)) (t "") ) ;_ end of cond ) ;_ end of strcat ) ;_ end of vl-mkdir (if (vl-file-directory-p path) path ) ;_ end of if ) ) ;_ end of cond ) ;_ end of defun (defun _kpblc-get-profile-name (profile) (vl-list->string (vl-remove-if-not (function (lambda (x) (or (<= 48 x 57) (<= 65 x 90) (<= 97 x 122) (= x 32) (<= 224 x 255) (<= 192 x 223) ) ;_ end of or ) ;_ end of lambda ) ;_ end of function (vl-string->list (cond (profile) (t (getvar "cprofile")) ) ;_ end of cond ) ;_ end of vl-string->list ) ;_ end of vl-remove-if ) ;_ end of vl-list->string ) ;_ end of defun (foreach profile (vl-remove-if (function (lambda (x / path) (or (not x) (/= (strcase (vl-filename-directory (vl-filename-directory (cdr (assoc "folder" x))))) (strcase (vl-filename-directory (cdr (assoc "menu" x)))) ) ;_ end of /= (= (strcase (cdr (assoc "menu" x))) (strcase (cdr (assoc "folder" x)))) ) ;_ end of or ) ;_ end of lambda ) ;_ end of function (mapcar (function (lambda (x / lang lst) (if (setq lang (vl-registry-read (strcat "HKEY_LOCAL_MACHINE" (apply (function strcat) (mapcar (function (lambda (a) (strcat "\\" a) ) ;_ end of lambda ) ;_ end of function (cdr (reverse (cddr (reverse (setq lst (_kpblc-conv-string-to-list x "\\")))))) ) ;_ end of mapcar ) ;_ end of apply ) ;_ end of strcat "LangAbbrev" ) ;_ end of vl-registry-read ) ;_ end of setq (list (cons "profile" x) (cons "lang" lang) (cons "menu" (vl-registry-read (strcat x "\\General Configuration") "MenuFile")) (cons "paths" (vl-registry-read (strcat x "\\General") "ACAD")) (cons "folder" (_kpblc-dir-create (strcat (vl-string-right-trim "\\" (getenv "AppData")) "\\Autodesk\\" (car (vl-remove nil (mapcar (function (lambda (a) (vl-registry-read (strcat "HKEY_LOCAL_MACHINE" (apply (function strcat) (mapcar (function (lambda (a) (strcat "\\" a) ) ;_ end of lambda ) ;_ end of function (cdr (reverse (cddr (reverse (setq lst (_kpblc-conv-string-to-list x "\\")) ) ;_ end of reverse ) ;_ end of cddr ) ;_ end of reverse ) ;_ end of cdr ) ;_ end of mapcar ) ;_ end of apply ) ;_ end of strcat a ) ;_ end of vl-registry-read ) ;_ end of lambda ) ;_ end of function '("ProductNameGlob" "ProductName" ) ) ;_ end of mapcar ) ;_ end of vl-remove ) ;_ end of car "\\" (car (vl-remove-if-not (function (lambda (x) (wcmatch x "R##*"))) lst) ) ;_ end of car "\\" lang "\\Support\\Profiles\\" (_kpblc-get-profile-name (last lst)) ;; И здесь имя профиля в файловой системе! ) ;_ end of strcat ) ;_ end of _kpblc-dir-create ) ;_ end of cons ) ;_ end of list ) ;_ end of if ) ;_ end of lambda ) ;_ end of function (get-all-reg-hives "HKEY_CURRENT_USER\\Software\\Autodesk\\AutoCAD") ) ;_ end of mapcar ) ;_ end of vl-remove (foreach file (vl-directory-files (vl-filename-directory (cdr (assoc "menu" profile))) (strcat (vl-filename-base (cdr (assoc "menu" profile))) ".*") 1 ) ;_ end of vl-directory-files (if (not (findfile (strcat (cdr (assoc "folder" profile)) "\\" file))) (vl-file-copy (strcat (vl-filename-directory (cdr (assoc "menu" profile))) "\\" file) (strcat (cdr (assoc "folder" profile)) "\\" file) ) ;_ end of vl-file-copy ) ;_ end of if ) ;_ end of foreach (vl-registry-write (strcat (cdr (assoc "profile" profile)) "\\General Configuration") "MenuFile" (strcat (vl-string-right-trim "\\" (cdr (assoc "folder" profile))) "\\" (vl-filename-base (cdr (assoc "menu" profile))) (cond ((vl-filename-extension (cdr (assoc "menu" profile)))) (t "") ) ;_ end of cond ) ;_ end of strcat ) ;_ end of vl-registry-write (if (not (member (cdr (assoc "folder" profile)) (vl-remove "" (_kpblc-conv-string-to-list (strcase (vl-registry-read (setq hive (strcat (cdr (assoc "profile" profile)) "\\General")) "ACAD")) ";" ) ;_ end of _kpblc-conv-string-to-list ) ;_ end of vl-remove ) ;_ end of member ) ;_ end of not (vl-registry-write hive "ACAD" (strcat (cdr (assoc "folder" profile)) ";" (vl-registry-read hive "ACAD")) ) ;_ end of vl-registry-write ) ;_ end of if ) ;_ end of foreach (alert "\nRestart AutoCAD!") (princ) ) ;_ end of defun |
У кода есть несколько недостатков:
- Код обрабатывает текущий профиль AutoCAD. Поэтому сразу после его выполнения необходимо выйти из AutoCAD
- При штатном удалении профиля нет никакой гарантии, что будут удалены все файлы, скопированные в соответствующий каталог
- Код проверен на версиях AutoCAD 2009-2016, русской и английской локализаций. Что будет в других версиях и сборках - не представляю
Код можно забрать тут: menuseparate.lsp
P.S. Конечно, было бы интересно сделать то же самое на .NET, но пока что не хватает ни времени, ни знаний
P.P.S. Немного измененный код: kpblc-menu. Как вложение - здесь
Вариант, работающий также на 2013: kpblc-menu. Оно же, как вложение.