Локализиция .NET-плагинов AutoCAD

Дата написания:
Дата редактирования:
Состояние: завершено (см. ниже "Внимание!")

    Космическая станция Mars Climate Orbiter, стоимостью 125 миллионов долларов, была потеряна 23 сентября 1999 года, потому что в одной из ответственных операций одна команда инженеров использовала метрические единицы измерения, в то время, как другая – дюймовую. При написании приложений для поставки на международный рынок следует учитывать различия культур и регионов.

Внимание! Решение данной задачи было мною выполнено и размещено здесь.

Задача

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

Архитектура решения

    Вообще, строго говоря, писать код следует сразу с учётом решения вопросов, связанных с локализацией, дабы потом не сидеть и не перелопачивать исходники, внося в них массовые поправки на эту тему. В дальнейшем, при необходимости добавления очередной локализации - этот процесс не займёт много времени, ибо в коде всё уже настроено и адаптировано для подобного рода изменений: всего-то потребуется - скопировать уже имеющийся resx-файл, переименовать его и перевести определённые в нём текстовые строки на нужный язык.
    Применительно к локализации следует выделить три параметра, которыми должен иметь возможность управлять пользователь:
  • Выбор локализации команд - на каком языке должна вводиться пользователем команда в командной строке AutoCAD, а так же выводиться подсказки в процессе её работы.
  • Выбор локализации пользовательского интерфейса - на каком языке должны отображаться надписи в диалоговых окнах, контекстных меню, всплывающих подсказках (если таковые будут присутствовать в плагине).
  • Выбор локализации справочной системы - выбор языка, на котором пользователь желает получать справочную информацию.
    Перечисленные выше настройки будут храниться во внешнем конфигурационном xml-файле (назовём его UserSettings.xml), а их действие будет распространяться на все загружаемые пользователем .net-библиотеки (созданные мною1). Указанный файл должен влиять на работу конкретного пользователя, т.к. у другого пользователя предпочтения, касающиеся локализации могут быть иными. По обозначенной выше причине UserSettings.xml следует хранить в пользовательском профиле Windows (у каждого пользователя этот файл будет свой). 

    Загружаемая пользователем в AutoCAD .net-библиотека должна быть построена по определённым правилам:
  • Информация, относящаяся к локализации (тексты, изображения флагов стран и т.п.) должна быть отделена от основного кода и вынесена в resx-файл(ы). Этот файл после компиляции будет собран в отдельную dll-библиотеку ресурсов.
  • Каждая .net-библиотека, загружаемая в AutoCAD, должна уметь управлять локализацией ресурсов библиотеки, поэтому следует создать шаблон проекта MS Visual Studio 2010, в котором будет реализован необходимый базовый функционал.
  • Справочная система должна быть оформлена в виде chm-файла - для каждой локализации своя версия chm-файла.

Ограничения

    Если в процессе работы AutoCAD пользователь в файле UserSettings.xml изменит настройки локализации, то не все из них смогут быть применены сразу же: изменение локализации уже загруженных команд (в рамках текущей сессии AutoCAD) вступит в силу только после перезапуска AutoCAD. 
    В то же время изменение локализаций пользовательского интерфейса2 и справочной системы не потребуют перезагрузки AutoCAD - они применяются моментально3...

Примечания
1 - я могу быть уверенным, что плагины, написанные мною будут "играть" по обозначенным мною правилам, что и позволит решить задачу, обозначенную в этой статье.
2 - локализация справочной системы, локализация пользовательского интерфейса и локализация команд на самом деле в .NET управляется одной и той же настройкой (System.Threading.Thread.CurrentThread.CurrentUICulture), а потому - какая локализация будет назначена команде, такая будет и у пользовательского интерфейса и у справки.  Изменение локализации в полной мере вступит в силу только после перезагрузки AutoCAD. Однако, поскольку существует вероятность того, что пользователь захочет использовать команды на одном языке, а справку читать на другом, то нужно как-то отделить управление локализацией справки от локализации команд. При этом, для смены локализации справочной системы желательно, чтобы не требовалась перезагрузка AutoCAD. Пришлось пойти на некоторую хитрость, чтобы реализовать это...
3 - на самом деле всё зависит от того, как написать код. Возможность моментально подхватить эти изменения есть, а то, как это по факту реализует программист - зависит от него самого...

Решение

Файл пользовательских настроек

    Для начала определимся с тем, как будем хранить настройки локализации:

   1:  <?xml version="1.0" encoding="utf-8"?>
   2:  <!--Файл UserSettings.xml
   3:  Настройки конкретного пользователя AutoCAD-->
   4:  <UserSettings>
   5:    <!--Блок настроек, отвечающих за локализацию-->
   6:    <Localization>
   7:      <!--Локализация команд-->
   8:      <Commands>en-US</Commands>
   9:      <!--Локализация пользовательского интерфейса-->
  10:      <GUI>ru-RU</GUI>
  11:      <!--Локализация справочной системы-->
  12:      <Manual>ru-RU</Manual>
  13:    </Localization>
  14:  </UserSettings>

Шаблон MS Visual Studio 2010

    Для того, чтобы не изобретать велосипед каждый раз, как буду писать новый .net-модуль под AutoCAD - следует создать проект MS Visual Studio 2010, который будет в последствии сохранён как шаблон, на основе которого будут строиться все последующие плагины. Для начала нужно определиться, какой функционал должен быть реализован в шаблоне:
  1. Подключены все необходимые библиотеки.
  2. Построена чётко определённая структура подкаталогов, которой должны придерживаться все .net-плагины (единообразная структура позволит быстро ориентироваться в таких модулях, а так же выполнять их программный анализ и обработку).
  3. В состав проекта включён файл Settings.xml - файл настроек текущего плагина.
  4. Созданы заготовки базовых классов.
  5. Реализованы методы чтения/записи настроек локализации, записанных в файле UserSettings.xml.
  6. Реализован метод, выполняющий смену локализации ресурсов, параллельно изменяющий содержимое ярлыка, указывающего на файл справочной системы (именно так мы сможем отделить локализацию справки от локализации команд, а так же моментально менять локализацию справочной системы без необходимости перезагрузки самого AutoCAD).
  7. Создан resx-файл, в котором должны храниться локализованные имена команд и их локализованные параметры.
  8. Создан resx-файл, в котором должны храниться локализованные ресурсы пользовательского интерфейса.
    Предварительно изучаем информацию, изложенную здесь, здесь, а так же внимательно читаем это и это. Если вас заинтересует более детальная информация по Unicode, то начать читать об этой кодировке можно отсюда. Шаблон будем создавать сами, без каких-либо "Wizard'ов"...
    Применительно к локализации плагинов AutoCAD имеется одна важная тонкость, которую нужно не забывать - имя resx-файла должно называться почти так же как называется класс, локализацию команд которого мы будем выполнять. "Почти" - потому что если соответствие будет полным, то MS Visual Studio 2010 на основе нашего resx-файла будет генерировать класс в том же пространстве имён и с таким же именем, как уже созданный нами класс команд. Как следствие - возникнет ошибка компиляции, т.к. в одном пространстве будет определено два класса с одинаковым именем. Поэтому имя resx-файла следует назначать таким же, какое назначено классу команд, но первая буква должна быть не прописной, а строчной. Т.о. будут генерироваться классы, к примеру Class1 и class1, а поскольку это уже будут разные имена, то конфликта при компиляции не возникнет. 


Comments