При организации интеграции между 1С:Предприятием 8 и базами 1С:Предприятия 7.7 через механизм OLE/COM часто возникает задача авторизации. Если перед подключением требуется интерактивно предоставить пользователю выбор конкретной учетной записи из списка пользователей 7.7, разработчик сталкивается с техническим тупиком: чтобы прочитать список пользователей штатными средствами через COM-объект v77.Application или v77s.Application, сначала необходимо уже успешно выполнить метод Initialize(), передав в него имя пользователя и пароль.
Разберем подробнее, какими способами можно решить эту задачу, с какими системными ограничениями придется столкнуться и почему на практике чаще всего выбирают альтернативный архитектурный подход.
Прежде чем программно извлекать список пользователей, проанализируем саму архитектуру взаимодействия двух систем. Как правило, интерактивный выбор учетной записи требуется из опасения, что пользователи будут блокировать сеансы друг друга. В платформе 1С 7.7 действует важное правило управления рабочими каталогами:
В большинстве практических задач правильнее отказаться от интерактивного выбора учетных записей конечных сотрудников и настроить специального технического пользователя:
OLE_Exchange).Посмотрим на пример стандартной инициализации COM-соединения в 1С 8:
КаталогБазы = "C:\Bases\1C77_Base";
ИмяПользователя = "OLE_Exchange";
ПарольПользователя = "SecretPassword";
Попытка
База77 = Новый COMОбъект("v77s.Application");
ПараметрыПодключения = База77.RMTrade.DefaultPrefix + " /D""" + КаталогБазы + """ /N""" + ИмяПользователя + """ /P""" + ПарольПользователя + """";
Результат = База77.Initialize(База77.RMTrade, ПараметрыПодключения, "NO_SPLASH_SHOW");
Если Не Результат Тогда
ВызватьИсключение "Не удалось инициализировать сеанс 1С 7.7";
КонецЕсли;
Исключение
Сообщить("Ошибка подключения к 7.7: " + ОписаниеОшибки());
КонецПопытки;
Такой подход снимает необходимость предварительного чтения списка пользователей и гарантирует параллельную работу любого количества подключений без конфликтов блокировки файлов.
Если бизнес-требования жестко диктуют вывод списка учетных записей (например, для разграничения персональной ответственности при запуске обработки), мы можем прочитать файл пользователей напрямую из файловой системы базы 7.7 без создания OLE-сеанса.
Список пользователей платформы 7.7 хранится в подкаталоге базы по пути usrdef\users.usr. Это текстовый контейнер в кодировке Windows-1251 (ANSI), однако внутри него присутствуют управляющие и бинарные символы (включая нулевые байты). Из-за этого стандартный объект ЧтениеТекста в 1С 8 может оборвать чтение на первом нулевом байте.
Разберем по шагам, как корректно загрузить файл через ДвоичныеДанные и извлечь системные имена пользователей:
Функция ПолучитьСписокПользователей77(КаталогБазы77) Экспорт
СписокПользователей = Новый Массив;
ПутьКФайлу = КаталогБазы77 + "\usrdef\users.usr";
ФайлНаДиске = Новый Файл(ПутьКФайлу);
Если Не ФайлНаДиске.Существует() Тогда
Возврат СписокПользователей;
КонецЕсли;
// Чтение в режиме разделяемого доступа через двоичные данные
Попытка
Двоичные = Новый ДвоичныеДанные(ПутьКФайлу);
СтрокаBase64 = Base64Строка(Двоичные);
Исключение
Сообщить("Файл пользователей заблокирован или недоступен: " + ОписаниеОшибки());
Возврат СписокПользователей;
КонецПопытки;
// Преобразуем данные в строку
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");
Двоичные.Записать(ИмяВременногоФайла);
Чтение = Новый ЧтениеТекста(ИмяВременногоФайла, КодировкаТекста.ANSI);
Содержимое = Чтение.Прочитать();
Чтение.Закрыть();
УдалитьФайлы(ИмяВременногоФайла);
// Поиск сигнатур пользователей через регулярные выражения
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Global = Истина;
RegExp.IgnoreCase = Истина;
RegExp.Pattern = "\{""User"",""([^""]+)""";
Совпадения = RegExp.Execute(Содержимое);
Для Каждого Совпадение Из Совпадения Цикл
ИмяЮзера = Совпадение.SubMatches(0);
Если СписокПользователей.Найти(ИмяЮзера) = Неопределено Тогда
СписокПользователей.Добавить(ИмяЮзера);
КонецЕсли;
КонецЦикла;
Возврат СписокПользователей;
КонецФункции
Важное предостережение: если в момент обращения к файлу users.usr какой-либо пользователь находится в окне авторизации 1С 7.7 (когда окно открыто, но логин и пароль еще не подтверждены), файл может быть временно заблокирован на уровне операционной системы. Всегда оборачивайте обращение к файлу в конструкцию Попытка ... Исключение.
Существуют внешние компоненты, разработанные специально для чтения списка пользователей (например, UsersDef.dll). Однако данная библиотека жестко завязана на структуры памяти запущенного экземпляра 1cv7.exe и не может работать автономно в 1С 8 как обычный COM-сервер.
Для обхода этого ограничения на форуме предложен обходной маневр:
users.usr из целевой рабочей базы в подкаталог usrdef нашей технической базы.UsersDef.dll через ЗагрузитьВнешнююКомпоненту() и считываем данные.Этот способ технически реализуем, но громоздок и медлителен по сравнению с прямым чтением файла или организацией сервисного пользователя.
При реализации любого взаимодействия между 1С 8 и 7.7 по OLE необходимо учитывать два критических системных фактора:
Новый COMОбъект("v77s.Application") завершится системной ошибкой «Класс не зарегистрирован». Вызов OLE-объектов 7.7 должен выполняться исключительно в контексте 32-битного толстого или тонкого клиента, либо через настройку выделенного COM+ приложения (через dcomcnfg и суррогатный процесс dllhost.exe).Initialize() без указания пользователя или пароля, 1С 7.7 попытается открыть модальное диалоговое окно авторизации. В клиентском сеансе пользователь увидит это окно, однако если запуск происходит в серверном контексте или службе, окно будет открыто в невидимой изолированной сессии («Session 0»), что приведет к бесконечному зависанию серверного потока.Для стабильной и масштабируемой работы интеграции наилучшим решением является создание отдельного пользователя в 1С 7.7 без указания персонального каталога. Это устраняет необходимость считывать списки сотрудников и предотвращает любые коллизии блокировок файлов при одновременной работе.