Как правильно определить имя клиентского компьютера при работе в RDP и настроить параметры сеанса в 1С

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

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

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

Особенности работы Модуля сеанса

Разберем ключевые технические ограничения Модуля сеанса в платформах 1С:Предприятие 8:

  1. Серверный контекст выполнения. Код Модуля сеанса всегда исполняется на стороне сервера 1С:Предприятия в привилегированном режиме. Стандартная функция ИмяКомпьютера() в Модуле сеанса возвратит имя сервера приложений, а не имя терминального клиента или физического ПК.
  2. Отсутствие доступа к контексту клиентского приложения. Модуль сеанса не имеет доступа к глобальным переменным Модуля приложения (таким как мИмяКомпьютера), а также к клиентским WSH-скриптам и системному окружению пользователя.
  3. Ограничения структуры модуля. В Модуле сеанса нельзя объявлять экспортируемые функции и процедуры (ключевое слово Экспорт вызовет ошибку компиляции). Также в нем отсутствуют раздел описания переменных и раздел основной программы.

Получение имени терминального клиента через WScript.Shell

Чтобы узнать имя компьютера, с которого пользователь подключился к серверу через удаленный рабочий стол (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С.

← На главную