Уже довольно давно я периодически слышу о потребности иметь в системе DIRECTUM глобальные переменные окружения, доступные из прикладной разработки. На этот счет зарегистрирована пока не реализованная идея. А совсем недавно тема поднималась на форуме. Но на самом деле такие переменные можно сделать своими руками, и в этой статье я хочу поделиться готовой реализацией.
Глобальное окружение представляет собой COM-сервер. В любом вычислении на ISBL мы можем к нему обратиться – положить туда нужные переменные, или получить оттуда переменные, которые сложили туда ранее в других вычислениях.
Прежде чем пользоваться окружением – его нужно установить. Для установки надо скопировать файл SBRteEnvironment.exe из приложенного архива
SBRteEnvironment.zip (230,11 Кб) на целевую машину, и затем зарегистрировать его командой SBRteEnvironment.exe /regserver. После этих незамысловатых действий окружение готово к работе. Если планируется использовать окружение в клиентском коде – его потребуется
установить на все клиентские машины.
Если потребуется удалить окружение – надо просто разрегистрировать его командой SBRteEnvironment.exe /unregserver, и удалить файл SBRteEnvironment.exe.
Имя регистрируемого COM-сервера - SBRteEnvironment.Environment. А это значит, что на ISBL мы его можем получать функцией CreateObject, следующим образом:
GlobalEnvironment = CreateObject('SBRteEnvironment.Environment')
Объект окружения имеет три метода:
В качестве примера я продемонстрирую, как удержать в глобальном окружении объект Microsoft Excel. Excel запускается довольно долго, поэтому имеет смысл после первого запуска не дать ему выгрузиться, чтобы следующее обращение к нему сработало быстрее. Чтобы
не давать ему выгрузиться – положим ссылку на него в глобальное окружение.
Для начала, создадим объект Excel, и добавим его в окружение:
ENV_VARIABLE_NAME = 'Excel' GlobalEnvironment = CreateObject('SBRteEnvironment.Environment') Excel = GlobalEnvironment.FindItem(ENV_VARIABLE_NAME) if VarIsNull(Excel) Excel = CreateObject('Excel.Application') GlobalEnvironment.SetVar(ENV_VARIABLE_NAME; Excel) ShowMessage('Переменная была добавлена в окружение.') else ShowMessage('Переменная уже есть в окружении.') endif
Теперь можем в любом месте поработать с подготовленным заранее объектом:
ENV_VARIABLE_NAME = 'Excel' GlobalEnvironment = CreateObject('SBRteEnvironment.Environment') Excel = GlobalEnvironment.FindItem(ENV_VARIABLE_NAME) if VarIsNull(Excel) Exit('Переменной нет в окружении. Необходимо ее добавить.') endif // Работаем с переменной Excel как обычно.
Если объект более нам не потребуется – удалим его из окружения:
ENV_VARIABLE_NAME = 'Excel' GlobalEnvironment = CreateObject('SBRteEnvironment.Environment') Excel = GlobalEnvironment.PopVar(ENV_VARIABLE_NAME)
Глобальное окружение реализовано в виде одиночки - шаблон проектирования Singleton. Приятной особенностью такой реализации является то, что мы можем обращаться к переменным в нем не только из разных вычислений в одном процессе, но даже и из разных процессов, запущенных одновременно. Например, если пользователь запустит сценарий, который по умолчанию выполняется в отдельном процессе – ISBL-код сценария получит доступ к переменным основного процесса. А значит, легко можно передать нужные данные из главного процесса в процесс сценария.
Глобальное окружение реализовано таким образом, что, будучи запущенным один раз – при первом вызове CreateObject('SBRteEnvironment.Environment'), - оно будет оставаться запущенным до тех пор, пока не будут завершены все процессы SBRte.exe и SBSce.exe. После завершения последнего из указанных процессов – глобальное окружение выгрузится автоматически. Именно такая реализация позволяет легко передавать переменные из одних вычислений в другие, и при этом не заботиться о сроке жизни самого глобального окружения.
Как я описал в деталях реализации – один процесс может легко получить доступ к объектам, которые были сложены в глобальное окружение другим процессом. Разумеется, эту особенность злоумышленник может попытаться использовать, чтобы перехватить данные, сложенные в окружение. Об этом стоит помнить – и либо не складывать данные требующие защиты в окружение, либо каким-то образом защищать их там.
При работе с глобальным окружением, рано или поздно возникает желание положить в него какие-то из объектов IS-Builder. В принципе, это можно делать, но тут может поджидать одна неочевидная на первый взгляд ловушка:
Выйти из этой ситуации достаточно просто – как только объект IS-Builder, который лежал в глобальном окружении, перестанет быть нужен, убирайте его из окружения с помощью PopVar.
С любезного разрешения руководства, я прикладываю к статье не только готовую утилиту SBRteEnvironment.zip (230.11 Кб), но и ее исходный код SBRteGlobalEnvironmentSource.zip (15,89 Кб). Не уверен, что у меня будет возможность заниматься развитием утилиты по пожеланиям, но думаю наличие исходного кода позволит доработать утилиту самостоятельно всем желающим. Надеюсь, что если кто-то будет ее дорабатывать - обязательно поделится с нашим сообществом. Утилита была разработана под Delphi 2007.
Надеюсь, что эта реализация глобального окружения окажется полезной на ваших проектах. В статье я постарался по возможности полно осветить работу с окружением, но если будут появляться вопросы – спрашивайте в комментариях к статье, постараюсь ответить.
Степан, это очень интересно!
Пару вопросов:
1. Ограничений на использование в зависимости от версии билдера нет?
2. Если на одной машине запущены 2 разных версии DIRECTUM, можно передавать между их вычислениями данные?
1. От версии зависимости быть не должно. Окружение само по себе не обращается к DIRECTUM - и поэтому никак не зависит от его версии.
2. Да, передача между разными версиями DIRECTUM должна работать. Так же должна работать и передача с не-ISBL-ным кодом - например с JavaScript в обложке папки, и т.п. Главное - чтобы на время передачи данных были запущены процессы SBRte/SBSce.
Ай, спасибо!
Заценю обязательно. Об опыте эксплуатации - доложусь.
Мне кажется есть более простой и надежный путь - создайте функцию работы с XML и простую табличку из двух полей. В одном имя пользователя в другом XML с переменными среды. Поиск по XPath довольно прост и не понадобится установка на каждой машине, плюс всега сохраняются данные, даже для веба. )))
Андрей, безусловно, можно реализовать такое окружение разными способами, и у них разных способов будут разные преимущества. В предложенном Вами варианте - доступ к окружению из веба действительно может оказаться удобной фишкой в некоторых сценариях работы.
Я видел разные реализации окружения, но у них у всех был один общий недостаток - туда нельзя сложить COM-объекты, а в некоторых сценариях требуются именно они. И одна из фишек предложенной мной реализации - возможность сохранить в окружении ссылки на COM-объекты. Я, правда, забыл явно указать этот момент в статье, спасибо что напомнили.
Например, можно сложить в окружение "тяжелые" объекты 1С, которые не хочется загружать-выгружать на каждый чих - именно для них искали глобальное окружение на форуме. Тут же и объекты самого DIRECTUM, а так же Word с Excel, которые я описал в примере. Я не знаю, как эти объекты можно сложить в xml, и думаю, что такой возможности в принципе нет.
Обнаружил в системных функциях (группа "Прочие функции") функцию "Окружение". Исходя из справки, она реализует тот же функционал, и не требуется никакой регистрации SBRteEnvironment.exe.
Александр, указанная Вами функция представляет лишь упрощенный доступ к окружению IObject.Environment текущего объекта, над которым выполняется вычисление. Окружение объекта является локальным для него, т.е. из "совсем другого" вычисления доступ к этому окружению получить не удастся.
Предложенное же мной окружение является глобальным - т.е. доступно из любого вычисления, даже из разных процессов, если они запущены на одной машине.
В 5.2.1 работает?
Вот такой код в 5.2.1 возвращает Empty.
Test = GlobalEnvironment.PopVar("TestName") же обнуляет переменные
Авторизуйтесь, чтобы написать комментарий