При работе в терминальном режиме (RDP) в клиент-серверных база данных 1С разработчики часто сталкиваются с задачей идентификации конкретного физического компьютера пользователя. Это необходимо для правильного привязывания торгового оборудования (фискальных регистраторов, сканеров штрихкодов, эквайринговых терминалов), настройки локальных прав или учета рабочих мест.
В этом материале мы проанализируем, почему вызов команд определения имени компьютера в обработчике УстановкаПараметровСеанса() приводит к ошибкам или возвращает имя сервера приложений вместо клиентской машины, и разберем правильный алгоритм решения задачи.
Разберем ключевые технические ограничения Модуля сеанса в платформах 1С:Предприятие 8:
ИмяКомпьютера() в Модуле сеанса возвратит имя сервера приложений, а не имя терминального клиента или физического ПК.мИмяКомпьютера), а также к клиентским WSH-скриптам и системному окружению пользователя.Экспорт вызовет ошибку компиляции). Также в нем отсутствуют раздел описания переменных и раздел основной программы.Чтобы узнать имя компьютера, с которого пользователь подключился к серверу через удаленный рабочий стол (RDP), используется переменная окружения ClientName. Выполнить считывание этой переменной можно с помощью COM-объекта WScript.Shell.
Рассмотрим пример функции для получения имени ПК в RDP-сессии:
Функция ПолучитьИмяКомпьютераТО() Экспорт
Перем мИмяКомпьютера;
Попытка
WSS = Новый COMОбъект("WScript.Shell");
WSSE = WSS.Environment("Process");
мИмяКомпьютера = ВРег(WSSE.Item("ClientName"));
Исключение
мИмяКомпьютера = "";
КонецПопытки;
Если ПустаяСтрока(мИмяКомпьютера) Тогда
мИмяКомпьютера = ИмяКомпьютера();
КонецЕсли;
Возврат мИмяКомпьютера;
КонецФункции
Посмотрим на алгоритм работы этой функции: сначала предпринимается попытка прочитать системную переменную ClientName текущего процесса Windows. Если пользователь работает в RDP, возвращается имя локального ПК. Если же запуск происходит вне RDP или возникают ошибки обращения к COM-объекту, система переходит к вызову стандартной функции ИмяКомпьютера().
Поскольку COM-объект WScript.Shell должен отрабатывать в контексте клиентской сессии, перенесем логику перезаписи параметра сеанса в процедуру клиентской инициализации, например в ПервоначальнаяИнициализация() общедоступного клиентского модуля или обработки запуска системы.
Проанализируем пример кода инициализации параметра сеанса на стороне клиента:
Процедура ОбновитьИнформацияОКомпьютере() Экспорт
Состояние("Обновляем информацию о компьютере ...");
// Получаем имя физического ПК или RDP-клиента
Имя = мвДоработки.ПолучитьИмяКомпьютераТО();
Комп = Справочники.Компьютеры.НайтиПоНаименованию(Имя, Истина);
Если Комп.Пустая() Тогда
Комп = Справочники.Компьютеры.СоздатьЭлемент();
Комп.УстановитьНовыйКод("");
Комп.Наименование = Имя;
Комп.Записать();
КонецЕсли;
// Актуализируем параметр сеанса для клиентской сессии
ПараметрыСеанса.Компьютер = Комп.Ссылка;
КонецПроцедуры
После успешного обновления значения ПараметрыСеанса.Компьютер отладчик покажет актуальную ссылку на справочник компьютеров. Однако в стандартном окне платформы Активные пользователи в колонке «Компьютер» по-прежнему может отображаться имя сервера.
Выясним причину этой особенности: значение в списке активных пользователей фиксируется платформой 1С на сетевом уровне в момент установления соединения. Программное изменение прикладных параметров сеанса из кода 1С не влияет на низкоуровневую системную информацию, отображаемую платформой в данном списке.
Для дополнительной проверки доступности клиентского компьютера (например, перед выполнением команд обмена с торговым оборудованием) можно применить пингование IP-адреса с помощью того же объекта WScript.Shell.
Разберем пример функции проверки связи по ping:
Функция PingIP_Адреса(IP_Адрес = "", Wss = Неопределено) Экспорт
Если ПустаяСтрока(IP_Адрес) Тогда
Возврат Ложь;
КонецЕсли;
Если Wss = Неопределено Тогда
Wss = Новый COMОбъект("WScript.Shell");
КонецЕсли;
// Возвращает 0 при успешном ответе от узла
КодВозврата = Wss.Run("ping -w 1500 -n 1 " + IP_Адрес, 0, Истина);
Возврат (КодВозврата = 0);
КонецФункции
Использование комплексного подхода — определение имени терминального клиента через переменную ClientName на клиенте и последующее обновление ПараметрыСеанса — позволяет корректно идентифицировать рабочие места кассиров и пользователей в любых конфигурациях 1С.