В данной статье приводится краткий обзор классов, используемых для автоматического копирования и установки требуемых файлов на все клиентские компьютеры, использующие Dynamics AX.
- Класс SysFileDeploymentFile
- Класс SysFileDeploymentDLL
- Пример реализации передачи файлов на клиентский компьютер: классы SysFileDeployment_HRM1, SysFileDeployment_HRM2
- Класс SysFileDeployment
- Исправление ошибки в классе SysFileDeployment
- Класс SysFileDeployer
- Действия, необходимые для автоматической установки на клиентские компьютеры внешних COM объектов
- Дополнение для AX4.0
Кашперук Иван Владимирович (kashperuk)
SysFileDeployment CLASS
В данной статье приводится краткий обзор классов, используемых для автоматической установки требуемых файлов на все клиентские компьютеры, использующие Dynamics AX.
Иерархия классов выглядит следующим образом (на примере Dynamics AX 3.0 SP3, build Number 1951.3730):
Более детально рассмотрим основные классы, наследуемые от класса SysFileDeployment.
Класс SysFileDeploymentFile
abstract class SysFileDeploymentFile extends SysFileDeployment
Класс выполняет проверку версий файла на клиенте и сервере.
Происходит это в методе isClientUpdated()
– для этого проверяется существование рассматриваемого файла на клиенте, а также сравнивается версия файла на клиенте и сервере. Под «версией» файла подразумевается дата его последнего изменения (modifiedDate), которая получается с помощью метода класса winAPI::getFileModifiedDate()
При этом используются вспомогательные методы parmClientVersion()
и parmServerVersion()
этого же класса.
Класс SysFileDeploymentDLL
abstract class SysFileDeploymentDLL extends SysFileDeploymentFile
Класс выполняет регистрацию (метод register()
) ActiveX компонент (файлы .OCX) и динамически подключаемых библиотек (файлы .DLL) в реестре Windows, а также обратную операцию (метод unregister()
).
Для регистрации используется класс winApi: вызывается процесс regsvr32.exe. При необходимости регистрация может быть произведена после перезагрузки системы – для этого в реестре в ключ #HKLM\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce помещается вызов процесса regsvr32.exe с передачей ему пути к требуемому файлу.
Заметим также, что в рассмотренном выше классе – предке данного класса – методы register
и unregister
не реализованы (не содержат кода). Это значит, что для классов, наследуемых непосредственно от класса SysFileDeploymentFile
, будет вызываться метод register класса-родителя SysFileDeployment, который не выполняет никаких действий. Таким образом регистрироваться в реестре будут только те файлы, для которых это необходимо.
Пример реализации передачи файлов на клиентский компьютер: классы SysFileDeployment_HRM1, SysFileDeployment_HRM2
На примере этих двух классов рассмотрим реализацию всех классов, наследуемых от вышерассмотренных двух. Как видно из иерархии объектов, приведенной выше, класс SysFileDeployment_HRM1
наследуется от класса SysFileDeploymentDLL
, а класс SysFileDeployment_HRM2
наследуется непосредственно от SysFileDeploymentFile
.
В обоих классах реализован метод fileName
, который возвращает название того файла, который необходимо синхронизировать с сервером. Этот метод должен быть реализован во всех классах наследниках SysFileDeployment
, так как в родителе он объявлен как абстрактный.
Отличием двух классов является то, что в классе SysFileDeployment_HRM2
необходимо реализовать еще и метод destinationPath
, который указывает на ту папку, в которой должен находиться файл на клиенте (тоже объявлен как абстрактный в классе SysFileDeployment
, но уже реализован в классе SysFileDeploymentDLL).
Класс SysFileDeployment
abstract class SysFileDeployment
Теперь более детально рассмотрим непосредственно класс SysFileDeployment
и его методы.
Основные три метода класса вызываются в методе run()
public boolean run() { boolean restartRequired = false; if (!this.isClientUpdated()) { restartRequired = this.copy(); this.register(); } return restartRequired; }
Метод isClientUpdated
перекрыт в рассмотренном выше наследнике SysFileDeploymentFile
.
Метод register
перекрыт в рассмотренном выше наследнике SysFileDeploymentDLL
.
Самый интересный метод – это метод copy
, который выполняет обновление файлов в случае необходимости (isClientUpdated == false
).
Приведу краткое описание работы метода copy:
- Считывается в контейнер файл с сервера
- Этим контейнером инициализируется экземпляр класса BinData
- Файл сохраняется на клиенте под временным именем (перед именем файла вставляется знак "_")
- Если выходной файл не существует, то переходим к пункту 5
- Если же выходной файл уже существует, то
- Происходит раз-регистрация его в реестре (если это применимо к данному файлу)
- Происходит попытка удаления файла
- Если файл удалился нормально, то переходим к пункту 5
- Если же файл все еще существует, то он, видимо, используется и заблокирован, а это значит, что необходимо переименовать его уже после перезагрузки системы. В этом случае метод copy возвращает true, что означает, что требуется перезагрузка системы.
- Сохраненный временный файл переименовывается, после чего время изменения файла клиентской версии файла устанавливается точно такое же, как и на файле с сервера (используется метод
WinApi::setFileTimeServer2Client
)
Исправление ошибки в классе SysFileDeployment
В классе SysFileDeployment
была допущена досадная ошибка. При поиске пути к необходимым файлам на стороне сервера используется метод
protected FilenameOpen sourcePath() { return xInfo::directory(DirectoryType::Include); }
Вроде бы все выглядит верно. Но из-за того, что экземпляр класса создается на клиентской стороне, этот метод возвращает путь к директории относительно указанной в конфигурационной утилите клиента. И если соответствующий путь на сервере отличается, то получаем ошибку на строке
container file = SysFileDeployment::getServerFile(this.sourcePath()+this.filename());
Для того, чтобы выбирался правильный путь, необходимо немного изменить код этого класса:
- Создать статический серверный метод
//AOSRunMode::Server //Returns the file path of the source file private server static FilenameOpen sourcePathServer() { return xInfo::directory(DirectoryType::Include); }
- В методе
sourcePath()
изменить код на приведенный ниже
protected FilenameOpen sourcePath() { // return xInfo::directory(DirectoryType::Include); return SysFileDeployment::sourcePathServer(); }
Класс SysFileDeployer
Все вышеописанные классы используются в классе SysFileDeployer, который запускается при загрузке системы в методе startup класса Info, после выполнения метода startupPost.
Описание этого класса приводится ниже, в совете по установке на клиентские компьютеры внешних COM объектов.
Действия, необходимые для автоматической установки на клиентские компьютеры внешних COM объектов
Приведенная ниже последовательность действий процитирована со страницы базы знаний http://erpkb.com/Axapta/AvtoregistracijaActiveX
Чтобы выполнить автоматическую установку внешних COM объектов на клиентские компьютеры, выполните следующие действия:
- разместить dll с компонентом в папке приложения Share\Include
- создать подкласс класса
SysFileDelpoymentDll
- перекрыть метод filename и написать в его теле return «имя_файла» (без пути)
- добавить classNum(Имя Вашего Подкласса) в перечень в методе класса
SysFileDeployer.filesToDeploy()
- увеличить на 1 значение макроса #define.CurrentVersion(1) в классе
SysFileDeployer
, методеClassDeclaration
После входа пользователя в систему осуществляется следующий набор действий:
- проверяется признак установленности файлов (он сохраняется в таблице
SysLastValue
) - если он отсутствует, то проверяется наличие на клиенте всех файлов, которые необходимо устанавливать
- если есть файл, отсутствующий на клиенте, запрашивается подтверждение установки у пользователя
- если установка подтверждена, необходимый файл переписывается на клиента в «%AxaptaClient%\Bin» и регистрируется.
Кашперук Иван Владимирович (kashperuk)
Дополнение для AX4.0 (12.06.07 от gl00mie)
Хорошее дополнение написал на axforum.info пользователь gl00mie.