Настройки уровня домена

Дата публикации: 05.03.2011
Дата редактирования: не редактировалась
Состояние: завершена

В нормальной организации все пользователи являются членами домена и каждый работает под своей учётной записью Windows. Кроме того - сотрудники каждой проектной группы входят в состав специально созданной для этого доменной группы. И наконец - все руководители групп проектирования входят в состав доменной группы, в которую только руководители входить и должны. Т.о. опираясь на информацию о том, в состав какой доменной группы входит пользователь, мы сможет легко узнать, в какой группе проектирования он числится и является ли руководителем группы.

Какого рода настройки и управление нам необходимо? Давайте подумаем... Наши пользователи работают в AutoCAD, загружая в него различные плагины, CUI-файлы, используя различные шаблоны, шрифты, блоки и т.д. и т.п. Хотелось бы иметь возможность централизованно управлять тем, что используют юзеры, а так же владеть механизмом, который бы контролировал, что всеми пользователями используется одна и та же версия того или иного ресурса, дабы не возникало неприятных моментов, когда после передачи чертежа от одного проектировщика другому, у того вдруг информация отображается не так, как должна в виду того, что версия используемого компонента (например шрифт или определение блока) у них различна. Немного отступив от темы, внесу маленькое уточнение: управление и конфигурирование следует организовывать на трёх уровнях:
  1. Уровень домена - настройки, влияющие на работу всех пользователей домена.
  2. Уровень доменной группы - настройки, влияющие на работу всех пользователей доменной группы.
  3. Уровень пользователя - настройки, влияющие на работу конкретного пользователя.
В рамках данной статьи, нас интересует п.1. Настройки уровня домена мы будем хранить в виде зашифрованного xml-файла. В рамках AdminCAD API все шифруемые xml-файлы имеют объектное представление в виде классов, реализующих интерфейс IXmlSerializable, а так же имеют статические методы Save и Load. Давайте подумаем, какие настройки нам нужны в общем конфигурационном файле уровня домена... Для начала создадим корневой элемент нашего xml-документа, в котором будет размещаться вся наша информация, а в виде атрибута укажем наименование нашей системы - значение этого атрибута будет использоваться в качестве наименования каталога нашей Системы как на сервере, так и на локальной машине:

   1:  <CommonSettings SystemName="AdminCAD">
   2:  </CommonSettings>

Первым делом разместим информацию о нашей компании - эти данные могут понадобиться нам в дальнейшем при генерации разного рода отчётов.

   1:    <!--Блок общей информации о компании-->
   2:    <CompanyInfo>
   3:      <!--Сокращённое наименование организации-->
   4:      <CompanyShortName>GPSM</CompanyShortName>
   5:      <!--Полное наименование организации-->
   6:      <CompanyFullName>ЗАО Институт Гипростроймост-Санкт-Петербург</CompanyFullName>
   7:      <!--Физический адрес организации-->
   8:      <CompanyAddress>"Институт Гипростроймост - Санкт-Петербург", Российская Федерация, 197198, Санкт-Петербург, ул. Яблочкова, 7Л</CompanyAddress>
   9:      <!--Логотип компании-->
  10:      <CompanyLogotype>%XmlPath.ServerDir%\Common\Settings\gpsm_logo.gif</CompanyLogotype>
  11:      <!--Контактные телефоны компании-->
  12:      <CompanyPhones>
  13:        <Phone Name="Канцелярия" Number="+7 (812) 777-77-77" />
  14:        <Phone Name="Приёмная" Number="+7 (812) 888-88-88" />
  15:      </CompanyPhones>
  16:      <!--Факсы компании-->
  17:      <CompanyFaxes>
  18:        <Fax Name="Канцелярия" Number="+7 (812) 777-77-77" />
  19:      </CompanyFaxes>
  20:      <!--Электронная почта компании-->
  21:      <CompanyEmails>
  22:        <Email Name="Секретари" Value="Any@oops.ru" />
  23:      </CompanyEmails>
  24:    </CompanyInfo>

Обратите внимание - в пути к файлу, содержащему логотип компании, содержится фрагмент текста, заключённый в символы '%' - это имя переменной, которое должно быть заменено на её значение при получении полного пути к файлу. На данный момент этой информации достаточно - более подробно переменные будут рассмотрены нами далее по ходу изложения материала. В группы телефонов, факсов и электронной почты можно добавлять новые данные помимо тех, что указаны выше, но удалять те, что я показал в разметке нельзя - они могут использоваться в коде (можно только изменять значения в атрибутах Value и Number).

Системе нужна информация о том, как узнать, кто является администратором CAD, а так же как называется та доменная группа, в состав которой входят только руководители групп проектирования. Помимо этого не лишним будет информация о том, как связаться с администратором CAD - эти данные, при необходимости, будут даны пользователям.

   1:    <!--Информация, необходимая для идентификации администратора CAD, его контактных данных,а так же информация о руководителях групп проектирования.-->
   2:    <Identification>
   3:      <!--Имя домена-->
   4:      <DomainName>hyprostroy</DomainName>
   5:      <!--Имя доменной группы, в состав которой входят только руководители групп проектирования-->
   6:      <TeamGroupName>ГИП</TeamGroupName>
   7:      <!--Информация об администраторе CAD-->
   8:      <CadAdminInfo>
   9:        <!--Логин администратора CAD-->
  10:        <AdminCadLogin>developer</AdminCadLogin>
  11:        <!--Имя администратора CAD-->
  12:        <AdminCadName>Андрей</AdminCadName>
  13:        <!--Отчество администратора CAD-->
  14:        <AdminCadMiddleName>Андреевич</AdminCadMiddleName>
  15:        <!--Фамилия администратора CAD-->
  16:        <AdminCadSurname>Бушман</AdminCadSurname>
  17:        <!--Внутренний контактный телефон для связи с администратором CAD-->
  18:        <AdminCadInnerPhone>240</AdminCadInnerPhone>
  19:        <!--Номер кабинета, в котором работает администратор CAD-->
  20:        <AdminCadCabinetNumber>206</AdminCadCabinetNumber>
  21:      </CadAdminInfo>
  22:    </Identification>

В процессе работы Системы, может возникнуть необходимость предоставления администратору CAD некоторой информации - например произошла ошибка при работе плагина. Помимо ошибок администратору CAD могут отправляться различные отчёты (если он того захочет).

   1:    <!--Настройки, для возможности автоматической отправки писем на электронную почту-->
   2:    <Emails Host="111.111.111.11" Port="11">
   3:      <!--Электронный почтовый ящик администратора CAD-->
   4:      <Email Key="CAD.Admin" Value="HelloAdminCAD@oops.ru" />
   5:      <!--Электронный почтовый ящик, на который следут отправлять отчёты об ошибках, возникших в процессе работы Системы-->
   6:      <Email Key="ErrorReports" Value="HelloError@oops.ru" />
   7:      <!--Электронный почтовый ящик,на который следует отправлять разного рода отчёты, запрашиваемые администратором CAD-->
   8:      <Email Key="WorkReports" Value="HelloWorkReport@oops.ru" />
   9:    </Emails>

В приведённый выше блок можно добавлять и другие адреса электронной почты, но те, что указаны выше - должны присутствовать обязательно, поскольку они используются в программном коде, т.е. можно изменять их значения (атрибут Value), но не имена ключей (атрибут Key).

В настройках мы так же будем хранить и ссылки на разного рода ресурсы, с тем, чтобы при необходимости можно было быстро предоставить пользователю нужную ссылку.

   1:    <!--Сайты, содержащие различного рода информацию о Системе-->
   2:    <Sites>
   3:      <!--Сетевая справка о системе-->
   4:      <Site Key="System.CAD.Help" Address="http://dump/default.aspx" />
   5:      <!--Сетевая справка стандарта предприятия по работе с САПР-->
   6:      <Site Key="AcadStandardHelp" Address="http://dump/default.aspx" />
   7:      <!--Сетевой адрес обучающих видеоуроков-->
   8:      <Site Key="AcadVideo" Address="http://dump/default.aspx" />
   9:      <!--Сетевой адрес,по которому размещена информация, по API Системы-->
  10:      <Site Key="AdminCadAPI" Address="http://dump/default.aspx" />
  11:    </Sites>

Можно добавлять новые элементы Site или изменять значения атрибутов Address тех, что перечислены выше, но, из тех, что я показал - удалять нельзя никаких элементов, поскольку они могут использоваться в коде.

То, в каких версиях AutoCAD может работать наш AdminCAD, зависит от состава серверного репозитория, а так же от разрешения на то администратора CAD. Для этого в составе конфигурационного файла уровня домена, прописываем блок этой информации.

   1:    <!--Версии AutoCAD, с которыми разрешено работать Системе-->
   2:    <AllowedAutoCADs>
   3:      <AutoCAD>17.2x86</AutoCAD>
   4:      <AutoCAD>17.2x64</AutoCAD>
   5:      <AutoCAD>18.0x86</AutoCAD>
   6:      <AutoCAD>18.0x64</AutoCAD>
   7:      <AutoCAD>18.1x86</AutoCAD>
   8:      <AutoCAD>18.1x64</AutoCAD>
   9:      <AutoCAD>18.2x86</AutoCAD>
  10:      <AutoCAD>18.2x64</AutoCAD>
  11:    </AllowedAutoCADs>

И это не просто указание всех существующих на сегодняшний день версий AutoCAD версий от 2009 и выше - наша Система на самом деле с лёгкостью управляет всеми ими (но это тема уже другой статьи). Администратор CAD может удалить из этого списка элемент, либо добавить новый - по своему усмотрению.

Все конфигурационные файлы, а так же файлы журналов, сценариев обновлений, файлы данных - шифруются, дабы излишне любопытные пользователи не могли запустить в них свои, порой кривые, пальчики. Для этого я написал простенький текстовый редактор - XML Crypto Editor For Admin CAD. С его помощью можно шифровать уже имеющиеся xml-файлы, либо дешифровывать уже зашифрованные (разумеется в нём можно и редактировать информацию). К сожалению на сегодняшний день я не реализовал в нём подсветки синтаксиса, нумерации строк, сворачивания/разворачивания блоков информации, но для начала мне хватит и такого редактора - позднее напишу реализацию в полностью графическом исполнении  (щёлкните мышью по рисунку, чтобы увеличить его).


Указанный мною редактор как-то должен определять, какие файлы являются зашифрованными, а какие нет. Поэтому в конфигурационном файле мы будем размещать блок информации о расширениях шифруемых нами файлов.

   1:    <!--Соглашения по расширениям xml-файлов, использующихся в Системе. Файлы, чьё расширение совпадает с одним из перечисленных в блоке Extentions - являются ЗАШИФРОВАННЫМИ xml-файлами.-->
   2:    <FileExtentions>
   3:      <!--Расширение для xml-файлов настроек (settings files)-->
   4:      <XmlSettingsFiles>set</XmlSettingsFiles>
   5:      <!--Расширение для xml-файлов данных (data files). В качестве данных могут выступать, к примеру, таблицы различных сортаментов.-->
   6:      <XmlDataFiles>xdat</XmlDataFiles>
   7:      <!--Расширение для xml-файлов, в которых содержится информация, согласно которой строится графический интерфейс (Custom User Interface) - меню, панели, вкладки и т.п.-->
   8:      <XmlCuiFiles>xcui</XmlCuiFiles>
   9:      <!--Расширение для xml-файлов, в которых описано содержимое различных каталогов (Directory Contents)-->
  10:      <XmlDirectoryContents>xdc</XmlDirectoryContents>
  11:      <!--Расширение для xml-файлов сценариев обновлений (Tasks)-->
  12:      <XmlTasks>tsk</XmlTasks>
  13:    </FileExtentions>

Удалять показанные выше элементы из группы FileExtentions или менять значения их имена - нельзя, поскольку они используются в программном коде. Можно только изменять значения. Помимо этого, в блок FileExtentions можно добавлять новые записи. На основе этой информации, редактор XML Crypto Editor For Admin формирует список расширений файлов (добавляя к общему списку три варианта: "*.*", "*.xml" и "*.config") для диалоговых окон открытия и сохранения файлов. Если администратор CAD для файла назначит расширение из показанного мною выше блока xml-данных - итоговый файл будет зашифрован. А если в качестве расширения будет указано xml, config или иное - данные будут сохранены в обычном текстовом файле, без шифрования и с использованием кодировки UTF-8  (щёлкните мышью по рисунку, чтобы увеличить его).



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

   1:    <!--Имена различных файлов (без указания расширений)-->
   2:    <FileNames>
   3:      <!--Имя файла общих настроек уровня домена-->
   4:      <CommonSettingsFileName>CommonSettings</CommonSettingsFileName>
   5:      <!--Имя файла ключа шифрования/дешифровки-->
   6:      <KeyFileName>Key</KeyFileName>
   7:      <!--Имя файла настроек плагина-->
   8:      <PluginSettingsFileName>Settings</PluginSettingsFileName>
   9:      <!--Имя файла настроек пользователя-->
  10:      <UserSettingsFileName>UserSettings</UserSettingsFileName>
  11:    </FileNames>

Т.о. если мы переименуем наш файл и его имя в приведённом выше xml-блоке, то нам не придётся перекомпилировать все приложения и плагины, которые в своём коде используют этот файл, поскольку его имя в них не зашито жёстко, а извлекается из файла настроек. В блок FileNames можно добавлять новые записи или изменять значение уже существующих, однако удалять те, что перечислены выше - нельзя, т.к. они используются в коде.

Теперь возьмёмся за структуру каталогов. Должна быть реализована возможность изменения структуры каталогов (если вдруг возникнет такая необходимость) без различного рода негативных последствий, типа перекомпилирования приложений или правки их конфигурационных файлов.  Мы будем активно использовать переменные. Каждая переменная имеет своё имя (ключ) и текстовое значение (значение ключа). В состав значения одной переменной может входить любое количество ключей других, существующих переменных и так до любого, нужного нам уровня вложенности. Это позволит нам менять структуру каталогов Системы, не нарушая при этом её целостности и функциональности. В нашем конфигурационном файле мы будем создавать свои переменные, присваивая им имена, начинающиеся с "Xml", чтобы мы могли отличать их от переменных операционной системы, которые мы так же можем использовать в значениях наших переменных, но с одним маленьким "но"... Давайте разберёмся, что это за "но" такое. В операционной системе Windows существуют переменные нескольких уровней: уровня машины, уровня пользователя и уровня процесса. Посмотрим на них, запустив на исполнение такой код:

   1:  //Создаём временный словарь, в который будем сохранять промежуточный результат
   2:  Dictionary<string, string> vars = new Dictionary<string, string>();
   3:  //Извлекаем значения всех системных переменных операционной системы
   4:  //Уровень локальной машины
   5:  EnvironmentVariableTarget et = EnvironmentVariableTarget.Machine;
   6:  Environment.GetEnvironmentVariables(et).Keys.Cast<string>().All(n => { vars.Add("Machine." + n, Environment.GetEnvironmentVariable(n, et)); return true; });
   7:  //Уровень пользователя
   8:  et = EnvironmentVariableTarget.User;
   9:  Environment.GetEnvironmentVariables(et).Keys.Cast<string>().All(n => { vars.Add("User." + n, Environment.GetEnvironmentVariable(n, et)); return true; });
  10:  //Уровень процесса
  11:  et = EnvironmentVariableTarget.Process;
  12:  Environment.GetEnvironmentVariables(et).Keys.Cast<string>().All(n => { vars.Add("Process." + n, Environment.GetEnvironmentVariable(n, et)); return true; });
  13:  Console.Title = "Переменные операционной системы Windows";
  14:  Console.WindowWidth = 120;
  15:  ConsoleColor defaultColor = Console.ForegroundColor;
  16:  vars.All(n => {
  17:      Console.ForegroundColor = ConsoleColor.Green;
  18:      Console.Write("{0}:", n.Key);
  19:      Console.ForegroundColor = defaultColor;
  20:      Console.WriteLine("{0}", n.Value); 
  21:      return true; });
  22:  Console.Read();

Результат выглядит примерно так  (щёлкните мышью по рисунку, чтобы увеличить его):


В нашем коде, мы перед каждой переменной поставили префикс, чтобы чётко видеть, какого уровня эта переменная (уровень машины, процесса или пользователя). Имена переменных не уникальны между уровнями: например переменная TEMP присутствует как на уровне машины, так и на уровнях пользователя и процесса. Отсюда вывод - если мы в нашем конфигурационном файле хотим использовать системные переменные операционной системы, нам нужно к их именам добавлять префиксы, указывающие тот уровень, с какого следует считывать значение переменной.
Выше мы уже приняли, что имена переменных, определённых в нашем конфигурационном файле, будут начинаться с 'Xml'. Имена системных переменных Windows будут у нас начинаться с 'Machine.', 'User.' и 'Process.' соответственно. Итак, мы с вами готовы рассмотреть блок, содержащий информацию о каталогах нашей системы.

   1:   <!--Информация о размещении каталогов с разного рода ресурсами представлена в блоке 'DirectoriesInfo' набором строковых переменных, которые могут использоваться в программе. Имя переменной указывается в атрибуте 'Key'. Для того, чтобы использовать имя переменной в составе строки, это имя следует обосабливать символом '%'.
   2:    Внимание! Помимо указанных в блоке 'DirectoriesInfo' переменных, автоматически вычисляется значение ряда следующих переменных (они так же войдут в словарь):
   3:    1. 'Xml.AcadVersion' - версия AutoCAD.
   4:    2. 'Xml.AcVerMajor' - старшая составляющая версии. Например для 17.2 это будет 17
   5:    3. 'Xml.AcVerMinor' - младшая составляющая версии. Например для 17.2 это будет 2
   6:    4. 'Xml.Platform' - версия платформы (x86 или x64).
   7:    5. 'Xml.SystemName' - имя СИСТЕМЫ, записанное в атрибуте 'SystemName' корневого элемента данного xml-файла настроек.
   8:    Прежде чем использовать значение, указанное в атрибуте 'Path', следует все имена переменных заменить на их значения-->
   9:    <Directories>
  10:      <!--Каталог (полный путь) к основному каталогу Системы, размещённому на сервере-->
  11:      <Directory Key="XmlPath.ServerDir" Path="D:\SERVER\%Xml.SystemName%" />
  12:      <!--Каталог (полный путь) Системы на локальной машине-->
  13:      <Directory Key="XmlPath.LocalCommonDir" Path="D:\%Xml.SystemName%" />
  14:      <!--Каталог (полный путь) в профиле пользователя-->
  15:      <Directory Key="XmlPath.UserDir" Path="%Process.AppData%\%Xml.SystemName%" />
  16:      <!--Каталог, в котором хранятся CUI-файлы (файлы меню AutoCAD)-->
  17:      <Directory Key="XmlPath.CUI" Path="%XmlPath.LocalCommonDir%\Dependent\%Xml.AcadVersion%\etc\CUI" />
  18:      <!--Каталог, в котором на сервере находятся оригиналы файлов настроек-->
  19:      <Directory Key="XmlPath.ServerConfig" Path="%XmlPath.ServerDir%\Settings" />
  20:      <!--Каталог, в котором находятся локальные копии файлов настроек-->
  21:      <Directory Key="XmlPath.LocalConfig" Path="%XmlPath.LocalCommonDir%\Settings" />
  22:      <!--Каталог, в котором находятся подкаталоги с настройками уровня доменных групп-->
  23:      <Directory Key="XmlPath.GroupSettings" Path="%XmlPath.LocalConfig%\GroupSettings" />
  24:      <!--Каталог, в котором хранятся журналы хеширования СЕРВЕРНЫХ каталогов (эти журналы создаёт администратор CAD и они хранятся на сервере).-->
  25:      <Directory Key="XmlPath.ServerDirectoryContents" Path="%XmlPath.ServerDir%\Journals" />
  26:      <!--Каталог, в котором хранятся журналы хеширования ЛОКАЛЬНЫХ каталогов-->
  27:      <Directory Key="XmlPath.LocalDirectoryContents" Path="%XmlPath.LocalCommonDir%\Updates\Journals" />
  28:      <!--Каталог, в котором хранятся ЕЩЁ НЕ ВЫПОЛНЕННЫЕ сценарии синхронизации каталогов-->
  29:      <Directory Key="XmlPath.LocalUpdateTasks" Path="%XmlPath.LocalCommonDir%\Updates\Tasks" />
  30:      <!--Каталог, в котором на сервере хранится версия синхронизатора, соответствующая текущей разрядности операционной системы-->
  31:      <Directory Key="XmlPath.ServerSynchronizer" Path="%XmlPath.ServerDir%\Tools\bin\%Xml.Platform%\Synchronizer" />
  32:      <!--Каталог, в котором на локальном компьютере хранится синхронизатор-->
  33:      <Directory Key="XmlPath.LocalSynchronizer" Path="%XmlPath.LocalCommonDir%\Tools\Synchronizer" />
  34:      <!--Каталог, в котором на сервере находится версия менеджера генерации журналов и сценариев обновлений, соответствующая текущей разрядности операционной системы-->
  35:      <Directory Key="XmlPath.ServerTaskWriter" Path="%XmlPath.ServerDir%\Tools\bin\%Xml.Platform%\TaskWriter" />
  36:      <!--Каталог, в котором на локальной машине находится менеджер генерации журналов и сценариев обновлений-->
  37:      <Directory Key="XmlPath.LocalTaskWriter" Path="%XmlPath.LocalCommonDir%\Tools\TaskWriter" />
  38:      <!--Каталог, в котором на сервере хранится версия стартера обновлений, соответствующая текущей разрядности операционной системы-->
  39:      <Directory Key="XmlPath.ServerBurro" Path="%XmlPath.ServerDir%\Tools\bin\%Xml.Platform%\Burro" />
  40:      <!--Каталог, в котором на локальном компьютере хранится стартер обновлений-->
  41:      <Directory Key="XmlPath.LocalBurro" Path="%XmlPath.LocalCommonDir%\Tools\Burro" />
  42:      <!--Каталог, являющийся локальным репозиторием плагинов, написанных на ObjectARX-->
  43:      <Directory Key="XmlPath.Arx" Path="%XmlPath.LocalCommonDir%\Dependent\%Xml.AcadVersion%\bin\%Xml.Platform%\ARX" />
  44:      <!--Каталог, являющийся локальным репозиторием плагинов, написанных на .Net-->
  45:      <Directory Key="XmlPath.Net" Path="%XmlPath.LocalCommonDir%\Dependent\%Xml.AcadVersion%\bin\%Xml.Platform%\Net" />
  46:      <!--Каталог, являющийся локальным репозиторием плагинов, написанных на VBA-->
  47:      <Directory Key="XmlPath.VBA" Path="%XmlPath.LocalCommonDir%\Undependent\VBA" />
  48:      <!--Каталог, являющийся локальным репозиторием плагинов, написанных на AutoLisp и/или VisualLisp-->
  49:      <Directory Key="XmlPath.LISP" Path="%XmlPath.LocalCommonDir%\Undependent\Lisp" />
  50:    </Directories>

В приведённом выше фрагменте xml-данных, каждая переменная представлена элементом Directory. Атрибут Key содержит в себе имя переменной, а атрибут Path - значение. В значении переменной могут фигурировать имена других переменных, которые при этом должны обосабливаться символом '%'. Обратите внимание на строку 15 - вы увидите, что системная переменная XmlPath.UserDir в своём значении содержит переменную Process.AppData, которая является системной переменной операционной системы Windows на уровне процесса. В приведённый выше блок xml-данных можно добавлять новые элементы Directory, но переименовывать ключи уже существующих, показанных выше переменных, или вовсе их удаление - запрещено, т.к. они используются в программном коде.

Обратите внимание на строки с 3 по 7 - в них перечислены имена переменных, которые создаются и инициализируются автоматически, в зависимости от того, применительно к какой версии AutoCAD (из тех, что установлены на локальной машине) мы хотим извлечь настройки.
Блок Directories  не является единственным блоком, содержащем в своём составе определение переменных. Ниже мы ещё рассмотрим блок OtherVariables, а пока - давайте перейдём к рассмотрению блока, содержащего в себе набор правил, согласно которым должны происходить различные проверки - блок RegexRules.

Блок RegexRules содержит в себе словарь регулярных выражений, на основании которых производятся проверки имён каталогов, файлов и т.п. Давайте посмотрим на него.

   1:    <!--Правила фильтрации, согласно которым должны выбираться или исключаться каталоги и файлы в процессе формирования журналов и задач обновлений. Правила формируются в виде РЕГУЛЯРНЫХ ВЫРАЖЕНИЙ, но в них можно использовать имена переменных, обособленные символом '%'. Прежде чем такое правило будет использовано - все имена переменных должны быть заменены их значениями-->
   2:    <RegexRules>
   3:      <!--Правило, согласно которому должна указываться версия AutoCAD-->
   4:      <RegexRule Key="versionRule" Rule="^[0-9]{2}\.[0-9]{1}$" />
   5:      <!--Правило, согласно которому должно определяться наличие указания версии AutoCAD в пути к каталогу или файлу-->
   6:      <RegexRule Key="dirHasVersion" Rule="\\[0-9]{2}\.[0-9]{1}(\\|$)" />
   7:      <!--Каталоги, которые следует исключать из набора-->
   8:      <RegexRule Key="excludeFolders-1" Rule="^(Sources|Help|Video|Burro|CryptoEditor|Synchronizer)$" />
   9:      <!--Каталоги, которые следует исключать из набора-->
  10:      <RegexRule Key="excludeFolders-2" Rule="^(Sources|Help|Video)$" />
  11:      <!--Файлы, которые следует исключать из набора-->
  12:      <RegexRule Key="excludeFiles-1" Rule="\.pdb$" />
  13:      <!--Правило, согласно которому не будет выбра ни один файл или каталог. Данное правило является своего рода заглушкой, если не нужно устанавливать никаких правил фильтрации.-->
  14:      <RegexRule Key="empty" Rule="^$" />
  15:      <!--Правило, согласно которому должны выбираться для дальнейшей загрузки библиотеки, написанные с использованием ObjectARX-->
  16:      <RegexRule Key="+arx" Rule="^.+((%Xml.AcVerMajor%\.%Xml.AcVerMinor%%Xml.Platform%)|(?&lt;!\d{2}\.\dx(86|64)))\.(dll|arx)$" />
  17:      <!--Правило, согласно которому из набора, полученного в правиле '+arx' следует исключить ряд элементов. Исключаются те, которые удовлетворяют текущему правилу-->
  18:      <RegexRule Key="-arx" Rule="^$" />
  19:      <!--Правило, согласно которому должны выбираться для дальнейшей загрузки библиотеки, написанные с использованием .Net API AutoCAD-->
  20:      <RegexRule Key="+net" Rule="^.+((%Xml.AcVerMajor%\.%Xml.AcVerMinor%%Xml.Platform%)|(?&lt;!\d{2}\.\dx(86|64)))\.dll$" />
  21:      <!--Правило, согласно которому из набора, полученного в правиле '+net' следует исключить ряд элементов. Исключаются те, которые удовлетворяют текущему правил-->
  22:      <RegexRule Key="-net" Rule="^$" />
  23:      <!--Правило, согласно которому должны выбираться для дальнейшей загрузки библиотеки, написанные на VBA-->
  24:      <RegexRule Key="+vba" Rule="^.+((%Xml.AcVerMajor%\.%Xml.AcVerMinor%%Xml.Platform%)|(?&lt;!\d{2}\.\dx(86|64)))\.dvb$" />
  25:      <!--Правило, согласно которому из набора, полученного в правиле '+vba' следует исключить ряд элементов. Исключаются те, которые удовлетворяют текущему правилу-->
  26:      <RegexRule Key="-vba" Rule="^$" />
  27:      <!--Правило, согласно которому должны выбираться для дальнейшей загрузки библиотеки, написанные на AutoLisp и VisualLisp-->
  28:      <RegexRule Key="+lisp" Rule="^.+((%Xml.AcVerMajor%\.%Xml.AcVerMinor%%Xml.Platform%)|(?&lt;!\d{2}\.\dx(86|64)))\.(lsp|fas|vlx)$" />
  29:      <!--Правило, согласно которому из набора, полученного в правиле '+lisp' следует исключить ряд элементов. Исключаются те, которые удовлетворяют текущему правилу-->
  30:      <RegexRule Key="-lisp" Rule="^$" />
  31:    </RegexRules>

Структура блока проста и понятна - каждое правило представлено в виде элемента RegexRule и имеет ключ (атрибут Key), по которому его можно идентифицировать, и собственно само правило (атрибут Rule). Можно добавлять новые записи в блок RegexRules, или изменять значения, прописанные в атрибуте Rule, но удалять те записи RegexRule, что показаны мною выше или изменять имена их ключей - запрещено, т.к. они используются в программном коде. Что такое "регулярное выражение" я объяснять не буду, ибо хоть тема эта и очень интересная, но к сожалению - объёмная. Администратору CAD умение работать с регулярными выражениями необходимо, хотя бы на базовом уровне, иначе он не сможет выполнять грамотное конфигурирование системы AdminCAD.

Обратите внимание на то, что в теле регулярного выражения можно использовать переменные!  Это можно увидеть, например, в строке 16, для правила под именем "+arx". Эта возможность очень важна, и я продемонстрирую это в другой статье.

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

   1:    <!--Задачи по синхронизации каталогов-->
   2:    <Tasks>
   3:      <!--Каталог, в котором находятся плагины (кроме тех, что написаны на AutoLisp/VisualLisp), специфичные для конкретной версии AutoCAD (с учётом разрядности операционной системы)-->
   4:      <Task FileName="Plugins_Arx_Net  %Xml.AcadVersion%%Xml.Platform%" SourceDirectory="%XmlPath.ServerDir%\Dependent\%Xml.AcadVersion%\bin\%Xml.Platform%" TargetDirectory="%XmlPath.LocalCommonDir%\Dependent\%Xml.AcadVersion%\bin" DirectoryExcludeRule="excludeFolders-1" FileExcludeRule="excludeFiles-1" />
   5:      <!--Каталог, в котором находятся различного рода данные, специфичные для конкретной версии AutoCAD-->
   6:      <Task FileName="DependentData %Xml.AcadVersion%%Xml.Platform%" SourceDirectory="%XmlPath.ServerDir%\Dependent\%Xml.AcadVersion%\etc" TargetDirectory="%XmlPath.LocalCommonDir%\Dependent\%Xml.AcadVersion%\etc" DirectoryExcludeRule="empty" FileExcludeRule="empty" />
   7:      <!--Каталог, в котором находятся плагины, написанные на AutoLisp/VisualLisp и VBA-->
   8:      <Task FileName="Plugins_Lisp_Vba" SourceDirectory="%XmlPath.ServerDir%\Undependent" TargetDirectory="%XmlPath.LocalCommonDir%\Undependent" DirectoryExcludeRule="excludeFolders-2" FileExcludeRule="empty" />
   9:      <!--Каталог, в котором содержатся данные, используемые в любой версии AutoCAD-->
  10:      <Task FileName="UndependentData" SourceDirectory="%XmlPath.ServerDir%\Common" TargetDirectory="%XmlPath.LocalCommonDir%\Common" DirectoryExcludeRule="empty" FileExcludeRule="empty" />
  11:      <!--Каталог, в котором содержатся настройки уровня доменных групп-->
  12:      <Task FileName="GroupSettings" SourceDirectory="%XmlPath.ServerDir%\Settings\GroupSettings" TargetDirectory="%XmlPath.LocalCommonDir%\Settings\GroupSettings" DirectoryExcludeRule="empty" FileExcludeRule="empty" />
  13:      <!--Каталог, в котором содержатся общие приложения Системы-->
  14:      <Task FileName="CommonTools %Xml.Platform%" SourceDirectory="%XmlPath.ServerDir%\Tools\bin\%Xml.Platform%" TargetDirectory="%XmlPath.LocalCommonDir%\Tools" DirectoryExcludeRule="excludeFolders-1" FileExcludeRule="excludeFiles-1" />   
  15:    </Tasks>


Как мы видим - каждая задача по синхронизации представлена элементом Task. На своё усмотрение администратор CAD может удалять или изменять представленные выше записи, а так же добавлять новые. Атрибут FileName указывает то, какое имя должно присваиваться файлу журнала. Обратите внимание на то, что формируя имя файла, так же можно использовать переменные (например в строке 6 в имени файла присутствует сразу две переменные). 
Атрибут SourceDirectory указывает на серверный каталог, участвующий в процессе синхронизации. Атрибут TargetDirectory указыват на локальный каталог. Т.е. указывается каталог-образец и целевой каталог. 

В каталогах серверного репозитория могут находиться такие каталоги и файлы, которые нам бы не хотелось копировать на локальную машину. Например в каталоге плагина мы можем хранить его исходники в подкаталоге Sources (в виде зашифрованного сжатого архива). Кроме того, в том же каталоге мы можем хранить обучающее видео (подкаталог Video), с помощью которого юзер может учиться работе с плагином. Требуется механизм, который позволит  нам указать правило, согласно которому не все каталоги и файлы будут бездумно копироваться в локальный репозиторий. В данном случае мы бы не хотели по сети гонять трафик с видео, а так же копировать юзеру исходники, которые ему абсолютно не нужны, но при этом занимают как объём на диске, так и время при синхронизации. Т.е. каталоги Sources и Video не должны участвовать в процессе синхронизации, хотя являются вложенными по отношению к серверному каталогу, участвующему в процессе синхронизиции в качестве источника. Механизм, позволяющий решить данную проблему в AdminCAD присутствует - это атрибуты DirectoryExcludeRule и FileExcludeRule в составе элемента Task. 

Атрибут DirectoryExcludeRule содержит имя ключа той записи из блока RegexRules (рассмотренного нами чуть выше), значение атрибута Rule которой следует использовать для исключения лишних каталогов из общего набора. Исключаются те каталоги, которые соответствуют правилу, указанному в атрибуте Rule.
Атрибут FileExcludeRule содержит имя ключа той записи из блока RegexRules (рассмотренного нами чуть выше), значение атрибута Rule которой следует использовать для исключения лишних файлов из общего набора. Исключаются те файлы, которые соответствуют правилу, указанному в атрибуте Rule.

Следующим блоком настроек является блок управления загрузкой плагинов в AutoCAD. То, что указано к загрузке в этом блоке, будет загружаться всем без исключения пользователям домена при старте AutoCAD, при условии, что Системе разрешено с ним работать (см. блок AllowedAutoCADs, рассмотренный нами выше).

   1:    <!--Перечень правил, согласно которым должны выбираться файлы плагинов для их загрузки в AutoCAD для всех пользователей домена-->
   2:    <LoadingTasks>
   3:      <!--Фильтры, согласно которым будут отбираться для загрузки плагины, написанные с помощью ObjectARX-->
   4:      <ARX>
   5:        <!--Атрибут 'Directory' содержит путь к каталогу, в котором должен осуществляться поиск файлов. В имени каталога можно использовать имена переменных, которые
   6:      определены в составе данного файла, в блоке 'Directories'. Имена переменных следует заключать между двумя символами '%'. 
   7:      В атрибуте 'IncludeFilters' указываются фильтры, на основании которых производится отбор нужных библиотек. Между собой фильтры следует разделять символом ';'.
   8:      Атрибут 'ExcludeFilters' (является необязательным) содержит перечень фильтров (разделённых символом ';'), с помощью которых отфильтровываются не нужные файлы из набора, полученного на основе фильтров, указанных в атрибуте 'IncludeFilters'.
   9:      Внимание: фильтры, указываемые в атрибутах 'IncludeFilters' и 'ExcludeFilters' - НЕ ЯВЛЯЮТСЯ РЕГУЛЯРНЫМИ ВЫРАЖЕНИЯМИ!
  10:      Атрибут 'Recursion' указывает, следует ли выполнять рекурсивный поиск по дочерним каталогам. 
  11:      Атрибут 'Use' указывает, следует ли обрабатывать данный элемент 'LoadingTask'. Элементов 'LoadingTask' может быть сколько угодно.-->
  12:        <LoadingTask Directory="%XmlPath.Arx%\bin\ARX" IncludeFilters="+arx" ExcludeFilters="-arx" Recursion="True" Use="True" />
  13:      </ARX>
  14:      <!--Фильтры, согласно которым будут отбираться для загрузки плагины, написанные с помощью .Net API AutoCAD-->
  15:      <NET>
  16:        <LoadingTask Directory="%XmlPath.Net%\bin\NET" IncludeFilters="+net" ExcludeFilters="-net" Recursion="True" Use="True" />
  17:      </NET>
  18:      <!--Фильтры, согласно которым будут отбираться для загрузки плагины, написанные с помощью AutoLisp и VisualLisp-->
  19:      <LISP>
  20:        <LoadingTask Directory="%XmlPath.LISP%" IncludeFilters="+lisp" ExcludeFilters="-lisp" Recursion="True" Use="True" />
  21:      </LISP>
  22:      <!--Фильтры, согласно которым будут отбираться для загрузки плагины, написанные с помощью VBA-->
  23:      <VBA>
  24:        <LoadingTask Directory="%XmlPath.VBA%\bin\VBA" IncludeFilters="+vba" ExcludeFilters="-vba" Recursion="True" Use="True" />
  25:      </VBA>
  26:    </LoadingTasks>

Блок информации, управляющий загрузкой плагинов в AutoCAD представлен элементом LoadingTasks, в составе которого присутствует четыре группы:
  1. ARX - группа задач по загрузке модулей, написанных с использованием ObjectARX.
  2. NET -  группа задач по загрузке модулей, написанных с помощью .Net API AutoCAD.
  3. LISP - группа задач по загрузке модулей, написанных с помощью AutoLisp или VisualLisp.
  4. VBA - группа задач по загрузке модулей, написанных с помощью VBA.
В составе каждой группы находятся элементы LoadingTask (в приведённом выше фрагменте каждая группа содержит только по одному элементу LoadingTask, но на самом деле их можно создавать сколько угодно, либо вообще удалить все, но тогда мы не сможем управлять загрузкой плагинов для всех пользователей домена). Элемент LoadingTask представляет собой задачу по загрузке плагинов. В атрибуте Directory указывается каталог, в котором следует искать плагины. 
Атрибут IncludeFilters содержит имя ключа той записи из блока RegexRules (рассмотренного нами чуть выше), значение атрибута Rule которой следует использовать для выбора тех файлов, которые следует загружать. 
Файлы, полученные с помощью правила, указанного в атрибуте IncludeFilters, затем проверяются фильтром ExcludeFilters, который содержит имя ключа той записи из блока RegexRules (рассмотренного нами чуть выше), значение атрибута Rule которой следует использовать для выбора тех файлов, которые следует исключить из общего набора. Т.о. фильтрация фалов проходит две "стадии очистки". 
Атрибут Recursion указыват, следует ли выполнять рекурсивный поиск файлов по подкаталогам директории, указанной в атрибуте Directory. 
Атрибут Use указывает на то, следует ли использовать данное правило (True - использовать, False - не использовать). Т.о. если администратор CAD не хочет, чтобы какая-то задача по загрузке плагинов выполнялась, ему вовсе не обязательно удалять её из конфигурационного файла - достаточно назначить её атрибуту Use значение False.

Последний блок называется OtherVariables содержит словарь групп переменных. Групп может быть сколько угодно, на усмотрение администратора CAD.

   1:    <!--Блок, предназначеный для хранения в виде словарей, различного рода информации. Информация объединяется в группы (элементы VariableGroup) и содержится в виде записей объектов Variable.-->
   2:    <OtherVariables>
   3:      <!--Настройки разрешений на загрузку для уровня доменной группы и уровня пользователя домена-->
   4:      <VariableGroup VarGroupName="PluginsLoadingSettings">
   5:        <!--Следует ли выполнять загрузку библиотек согласно задачам уровня доменных групп-->
   6:        <Variable Key="Xml.AllowLoadingByDomainGroupTasks" Value="true" />
   7:        <!--Следует ли выполнять загрузку библиотек согласно задачам уровня пользователя домена-->
   8:        <Variable Key="Xml.AllowLoadingByDomainUserTasks" Value="true" />
   9:      </VariableGroup>
  10:      <!--Блок переменных, для которых по какой-либо причине не имеет смысла создавать отдельную группу переменных-->
  11:      <VariableGroup VarGroupName="SingleVariables" />
  12:    </OtherVariables>

Каждая группа представлена элементом VariableGroup и содержит в своём составе неограниченное число элементов Variable. В этих переменных можно хранить любую нужную нам информацию.

Т.о. в этой статье мы подробно, полностью изучили содержимое общего конфигурационного файла уровня домена, который, по сути является сердцем системы AdminCAD. Конфигурационные файлы уровня домена и уровня пользователя будут рассмотрены в отдельных статьях. 

В AdminCAD API общий конфигурационный файл уровня домена представлен классом CommonSettings, реализующим интерфейс IXmlSerializable. Для того, чтобы использовать настройки применительно к конкретной версии AutoCAD, существует класс CommonSettingsWrapper. Демонстрация программной работы с этими классами будет выполнена в отдельной статье.

Comments