Как узнать IP-адрес компьютера средствами 1С?

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

В процессе разработки конфигураций и внешних обработок нередко возникает задача идентификации рабочего места пользователя по его сетевому адресу. Это может потребоваться для привязки торгового оборудования, логирования действий, разграничения прав доступа или диагностики сетевых соединений. Рассмотрим подробно, какими способами можно определить IP-адрес рабочей станции в среде 1С:Предприятие.

Прежде чем приступать к написанию кода, проанализируем важную архитектурную особенность клиент-серверного взаимодействия. Если код выполняется в серверном контексте (директива &НаСервере), то любые обращения к системным утилитам или объектам операционной системы вернут IP-адрес самого сервера 1С, а не компьютера пользователя. Для определения сетевого адреса рабочей станции клиента системные вызовы должны производиться строго на стороне клиента (директива &НаКлиенте) либо использовать специальные платформенные свойства текущего сеанса.

Способ 1. Использование WMI (Windows Management Instrumentation)

Разберем классический способ получения сетевых настроек под управлением Windows с помощью технологии WMI. В 1С обращение к WMI реализуется через создание объекта COMОбъект. Обратимся к системному классу Win32_NetworkAdapterConfiguration, который содержит параметры сетевых адаптеров.

Посмотрим на пример кода, позволяющий перебрать активные сетевые интерфейсы и вывести их IP-адреса:


&НаКлиенте
Процедура ПолучитьIPЧерезWMI()
    strComputer = ".";
    objWMIService = ПолучитьCOMОбъект("winmgmts:\\" + strComputer + "\root\CIMV2");
    colItems = objWMIService.ExecQuery("Select IPAddress from Win32_NetworkAdapterConfiguration Where IPEnabled = True", , 48);
    
    Для Каждого objItem Из colItems Цикл
        Если objItem.IPAddress <> Неопределено Тогда
            Для Каждого Стр Из objItem.IPAddress Цикл
                Сообщить("IP-адрес: " + Стр);
            КонецЦикла;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Рассмотрим альтернативную реализацию функции, использующую диспетчер WbemScripting.SWbemLocator. Этот вариант удобен для возврата первого найденного IP-адреса:


&НаКлиенте
Функция ПолучитьIPКлиентаWMI()
    SWBemlocator = Новый COMОбъект("WbemScripting.SWbemLocator");
    objWMIService = SWBemlocator.ConnectServer(".", "root\CIMV2");
    IPConfigSet = objWMIService.ExecQuery("Select IPAddress from Win32_NetworkAdapterConfiguration Where IPEnabled = True");
    
    Для Каждого Строка Из IPConfigSet Цикл
        Для Каждого Стр Из Строка.IPAddress Цикл
            Возврат Стр;
        КонецЦикла;
    КонецЦикла;
    
    Возврат "";
КонецФункции

Важный момент: на современных компьютерах часто установлено несколько адаптеров (физический Ethernet, Wi-Fi, VPN-соединения, виртуальные сетевые карты). Запрос с фильтром IPEnabled = True вернет адреса всех активных подключений. Чтобы определить основной адрес локальной сети, рекомендуется дополнительно проверять свойство DefaultIPGateway (шлюз по умолчанию), которое заполнено только у рабочего адаптера, имеющего выход во внешнюю сеть.

Способ 2. Вызов консольной утилиты ipconfig через WScript.Shell

Если требуется получить текстовый вывод сетевой конфигурации без глубокой работы со структурой WMI, разберем способ с запуском встроенной утилиты Windows ipconfig через объект WScript.Shell.

Посмотрим на пример перехвата стандартного потока вывода консоли:


&НаКлиенте
Функция ПолучитьВыводIpconfig()
    WshShell = Новый COMОбъект("WScript.Shell");
    Exec = WshShell.Exec("ipconfig");
    Результат = Exec.StdOut.ReadAll();
    Возврат Результат;
КонецФункции

После получения текста сетевой конфигурации можно извлечь адреса с помощью регулярных выражений или стандартных строковых функций. Данный способ является простым в реализации, однако имеет ограничения: при выполнении на доли секунды может мелькать окно командной строки, а разбор текста зависит от языка операционной системы (русская или английская локализация Windows выводит разные заголовки полей).

Способ 3. Штатные механизмы платформы 1С:Предприятие (без COM)

Вызовы COM-объектов имеют существенные недостатки: они не работают в операционных системах Linux и macOS, недоступны в веб-клиенте из-за песочницы браузера, а также могут блокироваться политиками безопасности Windows или профилями безопасности кластера 1С.

Начиная с версии платформы 8.3.17, разработчикам доступно штатное свойство IPАдресКлиента у объекта СеансИнформационнойБазы. Данный механизм работает без обращения к внешним утилитам и возвращает сетевой адрес клиентской машины так, как его видит сервер 1С.

Разберем по шагам получение адреса текущего сеанса на стороне сервера:


&НаСервере
Функция ПолучитьIPАдресТекущегоСеанса()
    НомерТекущегоСеанса = НомерСеансаИнформационнойБазы();
    Сеансы = ПолучитьСеансыИнформационнойБазы();
    
    Для Каждого ТекСеанс Из Сеансы Цикл
        Если ТекСеанс.НомерСеанса = НомерТекущегоСеанса Тогда
            Возврат ТекСеанс.IPАдресКлиента;
        КонецЕсли;
    КонецЦикла;
    
    Возврат "";
КонецФункции

Этот способ является наиболее предпочтительным для современных конфигураций, поскольку он не зависит от операционной системы клиента и не требует создания COM-объектов.

Способ 4. Определение внешнего (публичного) IP-адреса через HTTP-запрос

Если задача заключается не в определении адреса локальной подсети, а в получении внешнего «белого» IP-адреса, через который рабочая станция выходит в сеть Интернет (из-за NAT), ни WMI, ни утилита ipconfig не дадут нужного результата. В такой ситуации необходимо выполнить запрос к внешнему сервису, возвращающему IP отправителя.

Рассмотрим реализацию с использованием встроенного объекта HTTPСоединение:


&НаКлиенте
Функция ПолучитьВнешнийIP()
    Попытка
        Соединение = Новый HTTPСоединение("api.ipify.org", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
        Запрос = Новый HTTPЗапрос("/?format=text");
        Ответ = Соединение.Получить(Запрос);
        
        Если Ответ.КодСостояния = 200 Тогда
            Возврат СокрЛП(Ответ.ПолучитьТелоКакСтроку());
        КонецЕсли;
    Исключение
        Сообщить("Не удалось определить внешний IP: " + ОписаниеОшибки());
    КонецПопытки;
    
    Возврат "";
КонецФункции

Подводные камни и рекомендации

При выборе метода решения задачи обратим внимание на следующие факторы:

  1. Тип клиента: если пользователи работают через веб-клиент, прямое создание COM-объектов невозможно. Используйте штатные свойства сеанса на сервере либо заголовки веб-сервера.
  2. Кроссплатформенность: COM-объекты (WScript.Shell, WMI) функционируют только в среде Windows. Для Linux-клиентов подходит получение IP через сеанс информационной базы либо запуск команды hostname -I через метод ЗапуститьПриложение().
  3. Профили безопасности: при включенных профилях безопасности кластера серверов 1С создание COM-объектов и внешние сетевые вызовы на сервере могут быть запрещены настройками администратора.
← На главную