Почему КаталогВременныхФайлов() при COM-соединении возвращает путь клиентской машины и как получить путь сервера?

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

При интеграции баз данных 1С с использованием COM-соединителя (V83.COMConnector) разработчики часто сталкиваются с неожиданным поведением файловых функций. Например, процедура подключается к удаленной базе данных на другом сервере ЛВС, но вызов стандартной функции КаталогВременныхФайлов() возвращает локальный путь на машине, с которой выполняется вызов, а не каталог удаленного сервера. Разберем подробнее механики платформы 1С:Предприятие, вызывающие такое поведение, и выясним, как правильно запустить исполнение кода в контексте целевого сервера.

Архитектура COM-соединения и архитектура контекста

Проанализируем принцип работы компоненты V83.COMConnector. Библиотека COM-соединителя загружается непосредственно в процесс приложения-инициатора (это может быть тонкий клиент, толстый клиент или процесс rphost сервера-источника). При установке соединения с удаленной базой вызовы методов внешнего объекта выполняются внутри процесса-инициатора, а сеанс внешней базы работает в роли источника данных и исполнителя операций с базой данных.

Согласно документации платформы, функция КаталогВременныхФайлов() возвращает путь к рабочей папке пользователя, от имени которого запущено текущее приложение. Так как вызвающий процесс физически исполняется на локальном компьютере, функция возвращает значение локального профиля операционной системы.

Почему директивы компиляции #Если Сервер не помогают

Рассмотрим распространенную ошибку при попытке изменить контекст исполнения с помощью директив компиляции и флагов модулей.

Предположим, в модуле внешней базы с флагами Внешнее соединение и Сервер прописана следующая конструкция:


#Если ВнешнееСоединение Тогда
Процедура СделатьЧтоТоВДругойБазе() Экспорт
    ТутДелаемЕщеВызов();
КонецПроцедуры
#КонецЕсли

#Если Сервер Тогда
Процедура ТутДелаемЕщеВызов()
    // Ожидается, что этот код выполнится на целевом сервере
    ПутьКТемпу = КаталогВременныхФайлов();
КонецПроцедуры
#КонецЕсли

Использование инструкций #Если Сервер или #Если ВнешнееСоединение не переносит исполнение кода на удаленный рабочий процесс кластера (rphost). Эти инструкции являются инструкциями препроцессора и лишь управляют компиляцией кода в зависимости от контекста, в котором исходно загружен модуль. Если инициатор соединения вызвал метод через COM-коннектор, исполнение остается в контексте внешнего соединения на исходной машине.

Способы выполнения кода в контексте целевого сервера

Посмотрим на практические решения, которые позволяют гарантированно получить контекст кластера удаленного сервера и его локальный каталог временных файлов.

  1. Запуск фонового задания на целевом сервере

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

    Рассмотрим пример кода:

    
    // Выполняется через COM-соединение
    ПараметрыЗадания = Новый Массив;
    ПараметрыЗадания.Добавить(Параметр1);
    
    // Вызываем менеджер фоновых заданий внешней базы
    Задание = Соединение.ФоновыеЗадания.Создать("МойСерверныйМодуль.ИсполнитьНаСервере", ПараметрыЗадания);
    Задание.Запустить();
    Задание.ОжидатьЗавершения();
    

    Внутри процедуры МойСерверныйМодуль.ИсполнитьНаСервере вызов КаталогВременныхФайлов() вернет путь к папке временных файлов службы 1С (например, системной учетной записи usr1cv8) непосредственно на целевом сервере.

  2. Использование функции ПолучитьИмяВременногоФайла()

    Вместо ручной сборки путей через объединение строк с КаталогВременныхФайлов() рекомендуется использовать встроенную функцию ПолучитьИмяВременногоФайла(). При исполнении внутри серверного контекста фонового задания она автоматизирует создание уникального имени файла и корректно учитывает права доступа службы платформы.

  3. Создание COM-объекта на удаленном сервере (DCOM)

    Если требуется запустить сам COM-объект на другом физическом сервере, используется второй параметр конструктора Новый COMОбъект:

    COMОбъект = Новый COMОбъект("V83.COMConnector", ИмяУдаленногоСервера);

    Обратите внимание: данный вариант требует соответствующей настройки прав DCOM (Component Services) на целевой машине в Windows.

Передача файлов большого объема между серверами

Проанализируем важные ограничения при передаче объёмных данных (например, архивов размером 7–9 ГБ) через COM-соединение:

← На главную