Как программно определить IP-адрес компьютера пользователя в 1С:Предприятие 8.3

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

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

Способ 1. Использование встроенных функций платформы и анализ соединений

Первый и наиболее "чистый" с точки зрения архитектуры 1С способ — это обращение к списку активных соединений информационной базы. Платформа 1С:Предприятие предоставляет механизмы для программного получения информации о текущих сеансах. Давайте проанализируем ситуацию: нам нужно найти текущее соединение и извлечь из него сетевой адрес.

Рассмотрим алгоритм действий. Сначала мы определим уникальный идентификатор текущего сеанса, затем получим список всех соединений и найдем в нем наше. Важно помнить, что метод ПолучитьСоединенияИнформационнойБазы() требует наличия определенных прав доступа, поэтому этот код лучше выполнять в привилегированном модуле или под правами администратора. Для этой задачи есть обработка принудительного завершения сеансов пользователей 1С.

Разберем по шагам реализацию этой логики в коде:


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

Важный момент: в клиент-серверном варианте работы свойство ИмяКомпьютера объекта СоединениеИнформационнойБазы часто возвращает именно имя хоста, а не прямой IP-адрес. В таких случаях нам потребуются альтернативные инструменты, предоставляемые операционной системой.

Способ 2. Использование инструментария WMI (Windows Management Instrumentation)

Если стандартных средств платформы недостаточно, мы можем обратиться к возможностям операционной системы через COM-объекты. Один из самых мощных инструментов в ОС Windows — это WMI. Мы рассмотрим подробнее, как с помощью SWbemLocator получить список всех сетевых адаптеров. Стоит отметить, что вы также можете использовать COM-объекты на Python для 1С, чтобы расширить стандартный функционал получения системных данных.

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


Функция ПолучитьIPЧерезWMI() Экспорт
    Попытка
        // Создаем локатор для доступа к WMI
        Локатор = Новый COMОбъект("WbemScripting.SWbemLocator");
        // Подключаемся к локальному компьютеру в пространство имен CIMV2
        СервисWMI = Локатор.ConnectServer(".", "root\cimv2");
        
        // Формируем запрос для получения настроек сетевых адаптеров
        // Нас интересуют только те, у которых включен IP
        Запрос = "SELECT IPAddress FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True";
        РезультатЗапроса = СервисWMI.ExecQuery(Запрос);
        
        Для Каждого Объект Из РезультатЗапроса Цикл
            // IPAddress возвращается как массив строк
            Если Объект.IPAddress <> Неопределено Тогда
                Для Каждого ТекущийIP Из Объект.IPAddress Цикл
                    // Игнорируем IPv6 (содержат двоеточия), если нужен только IPv4
                    Если Найти(ТекущийIP, ":") = 0 Тогда
                        Возврат ТекущийIP;
                    КонецЕсли;
                КонецЦикла;
            КонецЕсли;
        КонецЦикла;
    Исключение
        Возврат "Ошибка доступа к WMI: " + ОписаниеОшибки();
    КонецПопытки;
    
    Возврат "Не найден";
КонецФункции

При использовании этого метода стоит учитывать, что он предназначен для работы под управлением Windows. Если вы используете тонкий клиент под Linux или macOS, данный код не сработает, и следует предусмотреть проверку типа операционной системы.

Способ 3. Выполнение системных команд и парсинг вывода

Существует еще один "классический" подход, который часто обсуждается на форумах — программный запуск утилиты ipconfig и чтение результата её работы. Этот метод хорош тем, что он не требует сложной настройки COM-объектов, но требует корректной обработки текстовых данных. Разберем, как реализовать это через временные файлы.

Алгоритм действий следующий:

  1. Создаем временный файл для хранения результата.
  2. Запускаем команду cmd /c ipconfig > [путь_к_файлу] в скрытом режиме.
  3. Читаем содержимое файла и ищем строку "IPv4-адрес" или "IP Address".
  4. Удаляем временный файл.

Посмотрим на пример реализации:


Функция ПолучитьIPИзКоманднойСтроки()
    ИмяФайлаРезультата = ПолучитьИмяВременногоФайла("txt");
    // Команда для выполнения
    Команда = "cmd /c ipconfig > """ + ИмяФайлаРезультата + """";
    
    // Запускаем приложение и ждем завершения (параметр Истина)
    ЗапуститьПриложение(Команда, , Истина);
    
    ЧтениеТекста = Новый ЧтениеТекста(ИмяФайлаРезультата, КодировкаТекста.OEM);
    ТекстРезультата = ЧтениеТекста.Прочитать();
    ЧтениеТекста.Закрыть();
    
    // Удаляем временный файл
    УдалитьФайлы(ИмяФайлаРезультата);
    
    // Простейший поиск строки с IP
    Позиция = Найти(ТекстРезультата, "IPv4");
    Если Позиция > 0 Тогда
        // Здесь можно добавить более точный парсинг строки
        Возврат "IP найден в выводе команды"; 
    КонецЕсли;
    
    Возврат "Не определено";
КонецФункции

Проанализируем ситуацию: основной недостаток этого метода — зависимость от языка операционной системы. В качестве альтернативы для быстрого получения адреса, с которым компьютер виден в сети, можно использовать готовый MyIP сервис на Python.

Особенности получения IP в веб-клиенте

Если ваша база опубликована на веб-сервере и пользователи работают через браузер, ситуация меняется. Код, запущенный в веб-клиенте, не имеет прямого доступа к аппаратным ресурсам компьютера. В этом случае выясним причину невозможности получения локального IP: браузер скрывает эти данные. Для решения проблем идентификации пользователей в таких условиях отлично подходит расширение для Chrome по передаче GUID клиента.

Для решения этой задачи в веб-клиенте обычно используются следующие подходы:

Пример обращения к внешнему сервису для определения внешнего IP-адреса:


&НаКлиенте
Функция ОпределитьВнешнийIP()
    HTTPСоединение = Новый HTTPСоединение("api.ipify.org");
    Запрос = Новый HTTPЗапрос("/");
    Ответ = HTTPСоединение.Получить(Запрос);
    Если Ответ.КодСостояния = 200 Тогда
        Возврат Ответ.ПолучитьТелоКакСтроку();
    КонецЕсли;
    Возврат "";
КонецФункции

Сравнение методов и рекомендации

Подводя итог нашему исследованию, можно сделать следующие выводы по выбору метода:

  1. Метод через сеансы 1С (ПолучитьСоединенияИнформационнойБазы) — идеален для административных задач внутри системы, когда важна привязка именно к сессии 1С.
  2. WMI — самый надежный и детальный способ для толстого и тонкого клиента под Windows.
  3. Командная строка — "запасной" вариант, если использование COM-объектов ограничено.
  4. Внешние HTTP-запросы — единственный способ узнать публичный IP-адрес клиента.

При реализации любого из этих методов мы рекомендуем всегда использовать блоки Попытка...Исключение, так как работа с внешними компонентами всегда сопряжена с риском возникновения ошибок. Таким образом, мы выяснили, что задача получения IP-адреса в 1С 8.3 имеет множество решений в зависимости от контекста выполнения кода.

← На главную