При работе в терминальном режиме (RDP или RemoteApp/RDA) 1С:Предприятие фактически исполняется на сервере, в то время как пользователь видит лишь «картинку» на своем локальном мониторе. Часто возникает задача инициировать действие на физическом компьютере пользователя: открыть ссылку в локальном браузере, запустить мессенджер (Telegram, WhatsApp) или открыть специфический файл, который не должен покидать пределы клиентской машины. Напрямую из кода 1С, исполняемого на сервере, достучаться до клиентской операционной системы невозможно из-за ограничений безопасности протокола RDP. Однако существуют проверенные архитектурные решения, которые мы разберем в этой статье.
Проанализируем самый простой в реализации метод, который не требует глубоких познаний в системном администрировании. Суть заключается в использовании промежуточного хранилища данных, к которому имеют доступ и сервер, и клиент.
Рассмотрим алгоритм реализации:
Пример структуры файла команды (JSON):
{
"action": "open_url",
"params": "https://t.me/username"
}
Разберем более продвинутый и быстрый способ, исключающий задержки файловой системы. Мы можем запустить на клиентском ПК миниатюрный веб-сервер, который будет ждать входящих запросов от 1С.
Для реализации нам необходимо знать IP-адрес клиента. В среде 1С его можно получить с помощью встроенной функции:
// Получаем IP-адрес клиентской машины в сессии RDP
ИмяКомпьютераКлиента = ПолучитьАдресКлиентскогоСоединения();
Выяснив IP-адрес, мы можем отправить HTTP-запрос из 1С. Рассмотрим пример простейшего агента на Python, который может работать в фоновом режиме на стороне клиента:
import subprocess
from http.server import BaseHTTPRequestHandler, HTTPServer
class CommandHandler(BaseHTTPRequestHandler):
def do_GET(self):
# В целях безопасности проверяем, что запрос пришел с сервера 1С
if self.client_address[0] != '192.168.1.100': # IP вашего сервера
self.send_response(403)
return
# Пример запуска Telegram ссылки
subprocess.run(["cmd", "/c", "start", "tg://resolve?domain=1c_dev"])
self.send_response(200)
self.end_headers()
server = HTTPServer(('0.0.0.0', 8000), CommandHandler)
server.serve_forever()
В коде 1С мы просто вызываем этот адрес через HTTPСоединение. Это позволяет мгновенно открывать мессенджеры или браузеры на локальном ПК.
Проанализируем наиболее профессиональный, но сложный в разработке метод. Протокол RDP поддерживает создание собственных виртуальных каналов связи между клиентской частью (mstsc.exe) и серверным приложением. Это именно тот механизм, через который работает проброс буфера обмена или USB-устройств.
Для реализации потребуются две части:
Этот метод является самым надежным, так как не зависит от сетевых настроек (Firewall), не требует знания IP-адреса и работает исключительно внутри защищенного туннеля RDP. Данные передаются только тому клиенту, который инициировал сессию, что исключает путаницу в многопользовательской среде.
Если ваша задача ограничивается открытием ссылок (HTTP, Mailto, Telegram), можно воспользоваться встроенным функционалом Windows под названием Host-to-Client Redirection. Рассмотрим, как это работает:
В операционной системе Windows (особенно при использовании ролей RDS) можно настроить политики, согласно которым определенные протоколы не обрабатываются сервером, а «пробрасываются» обратно клиенту. Это настраивается через групповые политики (GPO) или реестр по пути: HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services.
Если такая политика активна, то вызов команды ЗапуститьПриложение("https://google.com") в 1С приведет к тому, что браузер откроется не на сервере, а на локальном ПК пользователя. Существуют сторонние утилиты (например, RDP URL Redir), которые автоматизируют эту настройку, подменяя стандартный обработчик протоколов на сервере.
Проанализируем важный аспект: что делать, если на одном физическом компьютере запущено несколько терминальных сессий под разными учетными записями? При использовании PsExec или других административных инструментов запуска команд возникает риск запустить приложение не в том сеансе.
Для точного таргетирования мы рекомендуем использовать связку данных из WTS API. С помощью функции WTSQuerySessionInformation можно сопоставить идентификатор сессии 1С с именем клиентской машины (ClientName). Рассмотрим логику проверки:
ИмяКомпьютера() и ИмяПользователя().SessionID.Invoke-Command) всегда указываем конкретный сеанс, чтобы окно приложения открылось именно перед тем пользователем, который нажал кнопку в 1С.Важное замечание по безопасности: Любой метод, позволяющий серверу исполнять код на клиенте, — это потенциальная уязвимость. Если вы используете HTTP-агентов (Вариант 2), обязательно внедряйте проверку токена авторизации. В каждом запросе из 1С передавайте уникальный ключ, который известен только вашей системе, чтобы злоумышленники не могли удаленно управлять компьютерами ваших сотрудников.
Выбор решения зависит от инфраструктуры компании:
Помните, что использование PsExec часто блокируется современными антивирусными системами как потенциально опасное ПО (Remote Admin Tool), поэтому для корпоративных систем этот путь является наименее предпочтительным.