Соединение с агентом сервера.GetSecurityProfileAddIns

Методы · GetSecurityProfileAddIns

Получает разрешенные внешние компоненты.

Синтаксис

GetSecurityProfileAddIns(<Кластер>, <Профиль>)
Полное описание, параметры и ограничения

Соединение с агентом сервера.GetSecurityProfileAddIns (IServerAgentConnection.GetSecurityProfileAddIns)

Соединение с агентом сервера (IServerAgentConnection)

GetSecurityProfileAddIns (GetSecurityProfileAddIns)

Доступен, начиная с версии 8.3.3.

Синтаксис:
GetSecurityProfileAddIns(<Кластер>, <Профиль>)
Параметры:

<Кластер> (необязательный)
Тип: Кластер серверов.
Кластер серверов.

<Профиль> (обязательный)
Тип: Строка.
Имя профиля безопасности, которому принадлежит список.
Возвращаемое значение:
Тип: COMSafeArray.
Массив объектов Внешний компонент.
Описание:

Получает разрешенные внешние компоненты.

Доступность:

Интеграция.

Примечание:
Если профиль с этим именем не найден, то исключение.
Использование в версии:

Доступен, начиная с версии 8.3.3.

Методическая информация

Практические примеры

Создать отдельный COM-черновик: Внешний компонент

Фабрика создаёт редактируемое описание для последующей регистрации, но этот урок регистрацию не выполняет. Ресурсные параметры получены из собственного реального образца.

Где и как запускать

Полный модуль управляемой формы собственной пустой учебной конфигурации на отдельном локальном Windows-стенде 8.5.1.1343. Читаются только свой назначенный профиль и собственные ресурсы; подготовленные черновики не регистрируются. Здесь в 1С не запускался.

Подготовка

  1. Нужен отдельный собственный локальный серверный стенд 1С 8.5.1.1343 на Windows без рабочих баз. Здесь выполняется только авторская подготовка кода: реальное подключение агентом справочника не выполнялось.

  2. Администратор стенда заранее устанавливает сервер и регистрирует V85.COMConnector той же версии и разрядности, что серверный процесс учебной базы. Код не запускает regsvr32, не устанавливает платформу и не открывает COM 8.3 вместо 8.5.

  3. В своём стенде создайте единственный целевой кластер с точным именем УчебныйКластер85 и новую пустую серверную базу с именем УчебнаяБаза85. У описания этой базы задайте точное значение syntax-guide85:owned-com. Не переименовывайте рабочую базу или кластер ради обхода защит.

  4. У собственной учебной конфигурации задайте имя метаданных УчебнаяКонфигурацияСинтаксиса. Серверная функция должна выполняться на той же Windows-машине, что агент сервера и выбранный рабочий процесс: обращения жёстко ограничены 127.0.0.1.

  5. Заведите отдельные действительные учебные учётные данные администратора агента, администратора кластера и администратора базы с правом Администратор. В этих уроках имена и пароли намеренно должны быть непустыми; анонимный режим не используется.

  6. Создайте свою учебную обработку с управляемой формой. Реквизиты: ПортАгента и ПортКластера — Число без дробной части; КлючПроцесса, ИмяАгента, ПарольАгента, ИмяАдминистратораКластера, ПарольАдминистратораКластера, ИмяАдминистратораБазы, ПарольАдминистратораБазы, JSONРезультат — Строка; Занято — Булево, начально Ложь. Длина JSONРезультат 0.

  7. Поля трёх паролей выведите в Режиме пароля и не сохраняйте в настройках формы, истории или файле. JSONРезультат выведите многострочным полем только для просмотра. Добавьте команду ПолучитьУчебныйCOMСнимок с одноимённым клиентским обработчиком.

  8. Вставьте весь приведённый модуль формы, включая обе вспомогательные функции. ПортАгента берите из реальной настройки ragent, ПортКластера — из настройки менеджера кластера. Порт ras сюда не подходит.

  9. Первый раз оставьте КлючПроцесса пустым. Каталог покажет только локальные процессы выбранного учебного кластера. Скопируйте точный ключ порт|PID живого процесса из JSON, повторно введите очищенные пароли и повторите команду. PID не придумывайте; после перезапуска процесса получите каталог заново.

  10. Для диагностики соединений откройте одно или два своих клиентских окна УчебнаяБаза85 и выполните обычные учебные действия, например собственный константный запрос. Не создавайте нагрузку на рабочем сервере; измеряемые числа зависят от реальных действий.

  11. Снимок содержит только выбранные поля, не целые COM-объекты. Пароль СУБД, код разрешения входа, параметр блокировки и строка внешнего управления сеансами выводятся только как признаки наличия. Наличие строки не доказывает её корректность или доступность сервиса.

  12. Если вы сами запустите урок, произойдут административные обращения к своему локальному агенту и рабочему процессу. Настройки не меняются, сеансы не завершаются, база не создаётся и не удаляется. Здесь запуск в 1С и подключение не проверялись.

  13. На собственном стенде заранее создайте профиль с именем УчебныйПрофиль85 и описанием syntax-guide85:owned-com-profile. Назначьте его своей УчебнаяБаза85 как профиль обычного режима. Эти уроки профиль не создают, не назначают и не расширяют.

  14. Учитывайте разрешения самого профиля: серверному коду нужен разрешённый V85.COMConnector для административного чтения. Администратор стенда должен заранее разрешить свой реально зарегистрированный локальный соединитель; не включайте полный доступ ко всем COM-классам в рабочем профиле ради примера.

  15. Для каждого урока ресурса заранее зарегистрируйте в своём профиле ровно один собственный образец с указанным в уроке ключом и описанием syntax-guide85:owned-com-resource. Используйте реальные собственные пути, CLSID, контрольные суммы и шаблоны запуска. Строки в уроке не устанавливают сторонние компоненты.

  16. COM-описания имеют английские свойства и тип COMОбъект в BSL. Их нельзя создавать через Новый Виртуальный каталог или сравнивать ТипЗнч со строковым именем интерфейса из справки.

  17. Предварительно подготовьте реальный собственный образец УчебнаяКомпонента85 с маркером syntax-guide85:owned-com-resource. Черновик намеренно не будет зарегистрирован; исходный ресурс не переименовывайте.

&НаКлиенте
Процедура ПолучитьУчебныйCOMСнимок(Команда)
    Если Занято Тогда
        Возврат;
    КонецЕсли;
    Занято = Истина;
    Попытка
        JSONРезультат = УчебныйCOMСнимокНаСервере(ПортАгента, ПортКластера, КлючПроцесса,
            ИмяАгента, ПарольАгента, ИмяАдминистратораКластера, ПарольАдминистратораКластера,
            ИмяАдминистратораБазы, ПарольАдминистратораБазы);
    Исключение
        JSONРезультат = "Снимок не получен. Проверьте собственный Windows-стенд, COM 8.5, разрядность, порты, ключ процесса, учебные имена и права. Сырую ошибку с учётными данными не публикуйте.";
    КонецПопытки;
    ПарольАгента = "";
    ПарольАдминистратораКластера = "";
    ПарольАдминистратораБазы = "";
    Занято = Ложь;
КонецПроцедуры

&НаСервереБезКонтекста
Функция УчебныйCOMСнимокНаСервере(ПортАгента, ПортКластера, КлючПроцесса,
    ИмяАгента, ПарольАгента, ИмяАдминистратораКластера, ПарольАдминистратораКластера,
    ИмяАдминистратораБазы, ПарольАдминистратораБазы)
    Система = Новый СистемнаяИнформация;
    Если Система.ТипПлатформы <> ТипПлатформы.Windows_x86
        И Система.ТипПлатформы <> ТипПлатформы.Windows_x86_64 Тогда
        ВызватьИсключение "COM-урок требует серверного выполнения на Windows";
    КонецЕсли;
    Порты = Новый Массив;
    Порты.Добавить(ПортАгента);
    Порты.Добавить(ПортКластера);
    Для Каждого Порт Из Порты Цикл
        Если ТипЗнч(Порт) <> Тип("Число") Тогда
            ВызватьИсключение "Порты должны быть числами";
        КонецЕсли;
        Если Порт <> Цел(Порт) ИЛИ Порт < 1 ИЛИ Порт > 65535 Тогда
            ВызватьИсключение "Недопустимый порт локального стенда";
        КонецЕсли;
    КонецЦикла;
    Если ТипЗнч(КлючПроцесса) <> Тип("Строка") Тогда
        ВызватьИсключение "Ключ процесса должен быть строкой";
    КонецЕсли;
    УчётныеДанные = Новый Структура;
    УчётныеДанные.Вставить("ИмяАгента", ИмяАгента);
    УчётныеДанные.Вставить("ПарольАгента", ПарольАгента);
    УчётныеДанные.Вставить("ИмяКластера", ИмяАдминистратораКластера);
    УчётныеДанные.Вставить("ПарольКластера", ПарольАдминистратораКластера);
    УчётныеДанные.Вставить("ИмяБазы", ИмяАдминистратораБазы);
    УчётныеДанные.Вставить("ПарольБазы", ПарольАдминистратораБазы);
    Для Каждого Поле Из УчётныеДанные Цикл
        Если ТипЗнч(Поле.Значение) <> Тип("Строка") Тогда
            ВызватьИсключение "Учебные учётные данные должны быть строками";
        КонецЕсли;
        Если ПустаяСтрока(Поле.Значение) Тогда
            ВызватьИсключение "Введите все три непустые учебные пары учётных данных";
        КонецЕсли;
    КонецЦикла;
    ЛокальноеИмя = НРег(ИмяКомпьютера());
    АдресАгента = "tcp://127.0.0.1:" + Формат(ПортАгента, "ЧГ=0");
    Соединитель = Новый COMОбъект("V85.COMConnector");
    Агент = Соединитель.ConnectAgent(АдресАгента);
    Если Агент.ConnectionString <> АдресАгента Тогда
        ВызватьИсключение "Не совпала строка выбранного локального подключения";
    КонецЕсли;
    Агент.AuthenticateAgent(ИмяАгента, ПарольАгента);
    Кластер = Неопределено;
    СовпаденийКластера = 0;
    Для Каждого Найденный Из Агент.GetClusters() Цикл
        Если Найденный.ClusterName = "УчебныйКластер85"
            И УчебныйЛокальныйУзел(Найденный.HostName, ЛокальноеИмя)
            И Найденный.MainPort = ПортКластера Тогда
            Кластер = Найденный;
            СовпаденийКластера = СовпаденийКластера + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийКластера <> 1 Тогда
        ВызватьИсключение "Нужен единственный собственный локальный УчебныйКластер85 с указанным портом";
    КонецЕсли;
    Агент.Authenticate(Кластер, ИмяАдминистратораКластера, ПарольАдминистратораКластера);
    КраткаяБаза = Неопределено;
    СовпаденийБазы = 0;
    Для Каждого НайденнаяБаза Из Агент.GetInfoBases(Кластер) Цикл
        Если НайденнаяБаза.Name = "УчебнаяБаза85" И НайденнаяБаза.Descr = "syntax-guide85:owned-com" Тогда
            КраткаяБаза = НайденнаяБаза;
            СовпаденийБазы = СовпаденийБазы + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийБазы <> 1 Тогда
        ВызватьИсключение "Не найдена единственная собственная база с точным маркером описания";
    КонецЕсли;
    Каталог = Новый Массив;
    Процесс = Неопределено;
    СовпаденийПроцесса = 0;
    Для Каждого НайденныйПроцесс Из Агент.GetWorkingProcesses(Кластер) Цикл
        Если УчебныйЛокальныйУзел(НайденныйПроцесс.HostName, ЛокальноеИмя)
            И НайденныйПроцесс.MainPort >= 1 И НайденныйПроцесс.MainPort <= 65535
            И НайденныйПроцесс.MainPort = Цел(НайденныйПроцесс.MainPort)
            И НЕ ПустаяСтрока(НайденныйПроцесс.PID) Тогда
            Ключ = Формат(НайденныйПроцесс.MainPort, "ЧГ=0") + "|" + НайденныйПроцесс.PID;
            Каталог.Добавить(Новый Структура("Ключ,Хост", Ключ, НайденныйПроцесс.HostName));
            Если Ключ = КлючПроцесса Тогда
                Процесс = НайденныйПроцесс;
                СовпаденийПроцесса = СовпаденийПроцесса + 1;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    Если ПустаяСтрока(КлючПроцесса) Тогда
        Возврат СериализоватьСвойСнимок(Новый Структура("УчебныеПроцессы", Каталог));
    КонецЕсли;
    Если СовпаденийПроцесса <> 1 Тогда
        ВызватьИсключение "Нужен один живой локальный процесс с ключом из своего каталога";
    КонецЕсли;
    РабочееСоединение = Соединитель.ConnectWorkingProcess("tcp://127.0.0.1:" + Формат(Процесс.MainPort, "ЧГ=0"));
    СовпаденийПолнойБазы = 0;
    Для Каждого НайденнаяПолнаяБаза Из РабочееСоединение.GetInfoBases() Цикл
        Если НайденнаяПолнаяБаза.Name = КраткаяБаза.Name И НайденнаяПолнаяБаза.Descr = КраткаяБаза.Descr Тогда
            СовпаденийПолнойБазы = СовпаденийПолнойБазы + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийПолнойБазы <> 1 Тогда
        ВызватьИсключение "Рабочий процесс не подтвердил свою учебную базу";
    КонецЕсли;
    РабочееСоединение.AddAuthentication(ИмяАдминистратораБазы, ПарольАдминистратораБазы);
    База = Неопределено;
    СовпаденийПослеВхода = 0;
    Для Каждого НайденнаяПослеВхода Из РабочееСоединение.GetInfoBases() Цикл
        Если НайденнаяПослеВхода.Name = "УчебнаяБаза85" И НайденнаяПослеВхода.Descr = "syntax-guide85:owned-com" Тогда
            База = НайденнаяПослеВхода;
            СовпаденийПослеВхода = СовпаденийПослеВхода + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийПослеВхода <> 1 Тогда
        ВызватьИсключение "После аутентификации изменился выбор учебной базы";
    КонецЕсли;
    Снимок = Новый Структура;
    Снимок.Вставить("База", База.Name);
    Снимок.Вставить("ПроцессPID", Процесс.PID);
    Снимок.Вставить("ПортПроцесса", Процесс.MainPort);
    Если База.SecurityProfileName <> "УчебныйПрофиль85" Тогда
        ВызватьИсключение "Своей базе должен быть назначен УчебныйПрофиль85 обычного режима";
    КонецЕсли;
    Профиль = Неопределено;
    СовпаденийПрофиля = 0;
    Для Каждого НайденныйПрофиль Из Агент.GetSecurityProfiles(Кластер) Цикл
        Если НайденныйПрофиль.Name = База.SecurityProfileName
            И НайденныйПрофиль.Descr = "syntax-guide85:owned-com-profile" Тогда
            Профиль = НайденныйПрофиль;
            СовпаденийПрофиля = СовпаденийПрофиля + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийПрофиля <> 1 Тогда
        ВызватьИсключение "Нужен единственный назначенный собственный профиль с точным маркером";
    КонецЕсли;
    Снимок.Вставить("Профиль", Профиль.Name);
    Снимок.Вставить("ОписаниеПрофиля", Профиль.Descr);
    Образец = Неопределено;
    СовпаденийРесурса = 0;
    Для Каждого Ресурс Из Агент.GetSecurityProfileAddIns(Кластер, Профиль.Name) Цикл
        Если Ресурс.Name = "УчебнаяКомпонента85" И Ресурс.Descr = "syntax-guide85:owned-com-resource" Тогда
            Образец = Ресурс;
            СовпаденийРесурса = СовпаденийРесурса + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийРесурса <> 1 Тогда
        ВызватьИсключение "Подготовьте ровно один свой реальный ресурс с указанным ключом и маркером";
    КонецЕсли;
    Если СтрДлина(Образец.AddInHash) <> 28 Тогда
        ВызватьИсключение "У своего ресурса должна быть настоящая SHA-1/base64 контрольная сумма";
    КонецЕсли;
    БайтыХеша = Base64Значение(Образец.AddInHash);
    Если ТипЗнч(БайтыХеша) <> Тип("ДвоичныеДанные") Тогда
        ВызватьИсключение "Контрольная сумма должна декодироваться в двоичные данные";
    КонецЕсли;
    Если БайтыХеша.Размер() <> 20 ИЛИ Base64Строка(БайтыХеша) <> Образец.AddInHash Тогда
        ВызватьИсключение "Нужны 20 байт SHA-1 в канонической base64-строке";
    КонецЕсли;
    Суффикс = Строка(Новый УникальныйИдентификатор);
    НовыйКлюч = "УчебныйЧерновик85_" + Суффикс;
    Для Каждого ДоСоздания Из Агент.GetSecurityProfileAddIns(Кластер, Профиль.Name) Цикл
        Если ДоСоздания.Name = НовыйКлюч Тогда
            ВызватьИсключение "Сгенерированный новый ключ уже зарегистрирован";
        КонецЕсли;
    КонецЦикла;
    Черновик = Агент.CreateSecurityProfileAddIn();
    Если Черновик = Неопределено Тогда
        ВызватьИсключение "Фабрика должна вернуть отдельное описание ресурса";
    КонецЕсли;
    Черновик.Name = НовыйКлюч;
    Черновик.Descr = Образец.Descr + " — только предварительный объект";
    Черновик.AddInHash = Образец.AddInHash;
    Снимок.Вставить("ИсходныйКлюч", Образец.Name);
    Снимок.Вставить("КлючЧерновика", Черновик.Name);
    Снимок.Вставить("ОписаниеЧерновика", Черновик.Descr);
    Снимок.Вставить("ПроверкаAddInHash", Черновик.AddInHash = Образец.AddInHash);
    ЗарегистрированныхЧерновиков = 0;
    Для Каждого ПослеСоздания Из Агент.GetSecurityProfileAddIns(Кластер, Профиль.Name) Цикл
        Если ПослеСоздания.Name = Черновик.Name Тогда
            ЗарегистрированныхЧерновиков = ЗарегистрированныхЧерновиков + 1;
        КонецЕсли;
    КонецЦикла;
    Если ЗарегистрированныхЧерновиков <> 0 Тогда
        ВызватьИсключение "Новый ключ неожиданно зарегистрирован: не считать опыт изолированным";
    КонецЕсли;
    Снимок.Вставить("ЗарегистрированныхЧерновиков", ЗарегистрированныхЧерновиков);
    Снимок.Вставить("БезРегистрации", ЗарегистрированныхЧерновиков = 0);
    Возврат СериализоватьСвойСнимок(Снимок);
КонецФункции

&НаСервереБезКонтекста
Функция СериализоватьСвойСнимок(Снимок)
    Писатель = Новый ЗаписьJSON;
    Писатель.УстановитьСтроку();
    ЗаписатьJSON(Писатель, Снимок);
    Возврат Писатель.Закрыть();
КонецФункции


&НаСервереБезКонтекста
Функция УчебныйЛокальныйУзел(ИмяУзла, ЛокальноеИмя)
    Возврат НРег(ИмяУзла) = ЛокальноеИмя ИЛИ НРег(ИмяУзла) = "localhost" ИЛИ ИмяУзла = "127.0.0.1";
КонецФункции

Разбор по шагам

  1. Проверить имя учебной конфигурации, типы портов и реквизитов до COM. Порты целые в диапазоне 1..65535; секреты не сериализуются.

  2. ConnectAgent обращается только к 127.0.0.1. ConnectionString должна совпасть с построенной строкой без паролей. COM AuthenticateAgent принимает имя, пароль, в отличие от русскоязычного API ras.

  3. Выбрать УчебныйКластер85 по точному имени, локальному хосту и порту менеджера. Отсутствие или неоднозначность не заменяются выбором первого элемента.

  4. Проверить краткое описание УчебнаяБаза85 и точный маркер. Каталог живых локальных процессов позволяет взять настоящий порт|PID, а не подставить 1545 или придуманный PID.

  5. ConnectWorkingProcess использует найденный динамический порт процесса, не порт агента или ras. До аутентификации базы читаются только Name и Descr.

  6. AddAuthentication принимает только имя администратора базы и пароль, не дополнительный аргумент с именем базы. После него заново выбрать свою базу; полные поля читаются только далее.

  7. В конце показать явно перечисленные скалярные поля JSON. После успеха или ошибки очищаются все три пароля и снимается флаг Занято.

  8. После полного выбора собственного стенда проверить назначение обычного профиля, его точное имя и маркер описания. Чужой или неназначенный профиль не принимать.

  9. GetSecurityProfile… вызывается у агента с двумя аргументами: объект своего кластера и строковое имя собственного профиля. Это не русскоязычный метод объекта ras.

  10. Из фактического COMSafeArray взять ровно один ресурс по его реальному ключу и маркеру. Отсутствие/дублирование вызывает явную ошибку, а не создание фиктивного образца.

  11. AddInHash по COM-справке — SHA-1/base64. Чувствителен к регистру base64, не сравнивается через НРег как CLSID.

  12. Строка взята из собственного зарегистрированного ресурса, проверяется в памяти. Файл компоненты не читается и код не подключается.

  13. Правильные 20 байт не доказывают подпись, доверие поставщику или совпадение текущего файла с зарегистрированной суммой.

  14. Создать новый GUID-ключ и проверить его отсутствие в действующем списке до вызова фабрики.

  15. CreateSecurityProfileAddIn принимает ноль аргументов. Возвращённый COM-объект — отдельное описание, а не новый зарегистрированный ресурс.

  16. Сохранить точную SHA-1/base64 строку своей компоненты, не подключать саму компоненту.

  17. Менять только Черновик, не Образец. После подготовки повторно прочитать фактический список и подтвердить отсутствие нового ключа.

  18. Регистрационные методы RegSecurityProfile… и удаление UnregSecurityProfile… не вызываются. Повторное чтение — контроль отсутствия изменения, не регистрация.

Как проверить результат

  1. Проверки скопированных или намеренно ограниченных полей дают Истина на неизменённом собственном образце.

  2. ЗарегистрированныхЧерновиков=0, БезРегистрации=Истина; новый GUID-ключ отличается от исходного.

  3. Исходное разрешение и назначение профиля остались прежними. Нет активации CLSID, загрузки модуля, HTTP-запроса или запуска команды.

Ожидаемый результат

Подготовлен полноценный отдельный объект-описание на основе реального собственного ресурса с проверкой отсутствия регистрации.

На что обратить внимание

  1. COM здесь работает в серверном Windows-процессе. Loopback означает эту машину, не компьютер тонкого клиента; Linux и незарегистрированный соединитель этому уроку не соответствуют.

  2. Присутствие учебных имён и маркера не заменяет права доступа. Не запускайте в рабочем кластере; отделите стенд от production.

  3. Порт агента, порт менеджера кластера, порт ras и динамический порт рабочего процесса — разные значения.

  4. COMSafeArray перечисляется циклом Для Каждого. Это не Массив 1С и не список UUID ras; не приписывайте ему методы или свойства другой коллекции.

  5. Снимки и выбранные процессы могут устареть между запросами. После перезапуска повторите каталог; не пытайтесь автоматически завершить мешающий процесс.

  6. Сырые COM-ошибки могут раскрывать чувствительные сведения. Разбирайте подготовку в отладчике своего стенда, не добавляйте ОписаниеОшибки в публичный JSON.

  7. AddInHash по COM-справке — SHA-1/base64. Чувствителен к регистру base64, не сравнивается через НРег как CLSID.

  8. Строка взята из собственного зарегистрированного ресурса, проверяется в памяти. Файл компоненты не читается и код не подключается.

  9. Правильные 20 байт не доказывают подпись, доверие поставщику или совпадение текущего файла с зарегистрированной суммой.

  10. Для действующей политики нужна отдельная подтверждённая регистрация. Нельзя выдавать создание черновика за разрешённую операцию на сервере.

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

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

Полное описание получено у своего агента из своего назначенного профиля и проверенного зарегистрированного образца. Нет неизвестного входного объекта.

Где и как запускать

Полный модуль управляемой формы собственной пустой учебной конфигурации на отдельном локальном Windows-стенде 8.5.1.1343. Читаются только свой назначенный профиль и собственные ресурсы; подготовленные черновики не регистрируются. Здесь в 1С не запускался.

Подготовка

  1. Нужен отдельный собственный локальный серверный стенд 1С 8.5.1.1343 на Windows без рабочих баз. Здесь выполняется только авторская подготовка кода: реальное подключение агентом справочника не выполнялось.

  2. Администратор стенда заранее устанавливает сервер и регистрирует V85.COMConnector той же версии и разрядности, что серверный процесс учебной базы. Код не запускает regsvr32, не устанавливает платформу и не открывает COM 8.3 вместо 8.5.

  3. В своём стенде создайте единственный целевой кластер с точным именем УчебныйКластер85 и новую пустую серверную базу с именем УчебнаяБаза85. У описания этой базы задайте точное значение syntax-guide85:owned-com. Не переименовывайте рабочую базу или кластер ради обхода защит.

  4. У собственной учебной конфигурации задайте имя метаданных УчебнаяКонфигурацияСинтаксиса. Серверная функция должна выполняться на той же Windows-машине, что агент сервера и выбранный рабочий процесс: обращения жёстко ограничены 127.0.0.1.

  5. Заведите отдельные действительные учебные учётные данные администратора агента, администратора кластера и администратора базы с правом Администратор. В этих уроках имена и пароли намеренно должны быть непустыми; анонимный режим не используется.

  6. Создайте свою учебную обработку с управляемой формой. Реквизиты: ПортАгента и ПортКластера — Число без дробной части; КлючПроцесса, ИмяАгента, ПарольАгента, ИмяАдминистратораКластера, ПарольАдминистратораКластера, ИмяАдминистратораБазы, ПарольАдминистратораБазы, JSONРезультат — Строка; Занято — Булево, начально Ложь. Длина JSONРезультат 0.

  7. Поля трёх паролей выведите в Режиме пароля и не сохраняйте в настройках формы, истории или файле. JSONРезультат выведите многострочным полем только для просмотра. Добавьте команду ПолучитьУчебныйCOMСнимок с одноимённым клиентским обработчиком.

  8. Вставьте весь приведённый модуль формы, включая обе вспомогательные функции. ПортАгента берите из реальной настройки ragent, ПортКластера — из настройки менеджера кластера. Порт ras сюда не подходит.

  9. Первый раз оставьте КлючПроцесса пустым. Каталог покажет только локальные процессы выбранного учебного кластера. Скопируйте точный ключ порт|PID живого процесса из JSON, повторно введите очищенные пароли и повторите команду. PID не придумывайте; после перезапуска процесса получите каталог заново.

  10. Для диагностики соединений откройте одно или два своих клиентских окна УчебнаяБаза85 и выполните обычные учебные действия, например собственный константный запрос. Не создавайте нагрузку на рабочем сервере; измеряемые числа зависят от реальных действий.

  11. Снимок содержит только выбранные поля, не целые COM-объекты. Пароль СУБД, код разрешения входа, параметр блокировки и строка внешнего управления сеансами выводятся только как признаки наличия. Наличие строки не доказывает её корректность или доступность сервиса.

  12. Если вы сами запустите урок, произойдут административные обращения к своему локальному агенту и рабочему процессу. Настройки не меняются, сеансы не завершаются, база не создаётся и не удаляется. Здесь запуск в 1С и подключение не проверялись.

  13. На собственном стенде заранее создайте профиль с именем УчебныйПрофиль85 и описанием syntax-guide85:owned-com-profile. Назначьте его своей УчебнаяБаза85 как профиль обычного режима. Эти уроки профиль не создают, не назначают и не расширяют.

  14. Учитывайте разрешения самого профиля: серверному коду нужен разрешённый V85.COMConnector для административного чтения. Администратор стенда должен заранее разрешить свой реально зарегистрированный локальный соединитель; не включайте полный доступ ко всем COM-классам в рабочем профиле ради примера.

  15. Для каждого урока ресурса заранее зарегистрируйте в своём профиле ровно один собственный образец с указанным в уроке ключом и описанием syntax-guide85:owned-com-resource. Используйте реальные собственные пути, CLSID, контрольные суммы и шаблоны запуска. Строки в уроке не устанавливают сторонние компоненты.

  16. COM-описания имеют английские свойства и тип COMОбъект в BSL. Их нельзя создавать через Новый Виртуальный каталог или сравнивать ТипЗнч со строковым именем интерфейса из справки.

  17. Подготовьте свой ресурс типа Внешний компонент с ключом УчебнаяКомпонента85 и точным описанием syntax-guide85:owned-com-resource. Используйте реальную настройку, а не данные из произвольного примера.

&НаКлиенте
Процедура ПолучитьУчебныйCOMСнимок(Команда)
    Если Занято Тогда
        Возврат;
    КонецЕсли;
    Занято = Истина;
    Попытка
        JSONРезультат = УчебныйCOMСнимокНаСервере(ПортАгента, ПортКластера, КлючПроцесса,
            ИмяАгента, ПарольАгента, ИмяАдминистратораКластера, ПарольАдминистратораКластера,
            ИмяАдминистратораБазы, ПарольАдминистратораБазы);
    Исключение
        JSONРезультат = "Снимок не получен. Проверьте собственный Windows-стенд, COM 8.5, разрядность, порты, ключ процесса, учебные имена и права. Сырую ошибку с учётными данными не публикуйте.";
    КонецПопытки;
    ПарольАгента = "";
    ПарольАдминистратораКластера = "";
    ПарольАдминистратораБазы = "";
    Занято = Ложь;
КонецПроцедуры

&НаСервереБезКонтекста
Функция УчебныйCOMСнимокНаСервере(ПортАгента, ПортКластера, КлючПроцесса,
    ИмяАгента, ПарольАгента, ИмяАдминистратораКластера, ПарольАдминистратораКластера,
    ИмяАдминистратораБазы, ПарольАдминистратораБазы)
    Система = Новый СистемнаяИнформация;
    Если Система.ТипПлатформы <> ТипПлатформы.Windows_x86
        И Система.ТипПлатформы <> ТипПлатформы.Windows_x86_64 Тогда
        ВызватьИсключение "COM-урок требует серверного выполнения на Windows";
    КонецЕсли;
    Порты = Новый Массив;
    Порты.Добавить(ПортАгента);
    Порты.Добавить(ПортКластера);
    Для Каждого Порт Из Порты Цикл
        Если ТипЗнч(Порт) <> Тип("Число") Тогда
            ВызватьИсключение "Порты должны быть числами";
        КонецЕсли;
        Если Порт <> Цел(Порт) ИЛИ Порт < 1 ИЛИ Порт > 65535 Тогда
            ВызватьИсключение "Недопустимый порт локального стенда";
        КонецЕсли;
    КонецЦикла;
    Если ТипЗнч(КлючПроцесса) <> Тип("Строка") Тогда
        ВызватьИсключение "Ключ процесса должен быть строкой";
    КонецЕсли;
    УчётныеДанные = Новый Структура;
    УчётныеДанные.Вставить("ИмяАгента", ИмяАгента);
    УчётныеДанные.Вставить("ПарольАгента", ПарольАгента);
    УчётныеДанные.Вставить("ИмяКластера", ИмяАдминистратораКластера);
    УчётныеДанные.Вставить("ПарольКластера", ПарольАдминистратораКластера);
    УчётныеДанные.Вставить("ИмяБазы", ИмяАдминистратораБазы);
    УчётныеДанные.Вставить("ПарольБазы", ПарольАдминистратораБазы);
    Для Каждого Поле Из УчётныеДанные Цикл
        Если ТипЗнч(Поле.Значение) <> Тип("Строка") Тогда
            ВызватьИсключение "Учебные учётные данные должны быть строками";
        КонецЕсли;
        Если ПустаяСтрока(Поле.Значение) Тогда
            ВызватьИсключение "Введите все три непустые учебные пары учётных данных";
        КонецЕсли;
    КонецЦикла;
    ЛокальноеИмя = НРег(ИмяКомпьютера());
    АдресАгента = "tcp://127.0.0.1:" + Формат(ПортАгента, "ЧГ=0");
    Соединитель = Новый COMОбъект("V85.COMConnector");
    Агент = Соединитель.ConnectAgent(АдресАгента);
    Если Агент.ConnectionString <> АдресАгента Тогда
        ВызватьИсключение "Не совпала строка выбранного локального подключения";
    КонецЕсли;
    Агент.AuthenticateAgent(ИмяАгента, ПарольАгента);
    Кластер = Неопределено;
    СовпаденийКластера = 0;
    Для Каждого Найденный Из Агент.GetClusters() Цикл
        Если Найденный.ClusterName = "УчебныйКластер85"
            И УчебныйЛокальныйУзел(Найденный.HostName, ЛокальноеИмя)
            И Найденный.MainPort = ПортКластера Тогда
            Кластер = Найденный;
            СовпаденийКластера = СовпаденийКластера + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийКластера <> 1 Тогда
        ВызватьИсключение "Нужен единственный собственный локальный УчебныйКластер85 с указанным портом";
    КонецЕсли;
    Агент.Authenticate(Кластер, ИмяАдминистратораКластера, ПарольАдминистратораКластера);
    КраткаяБаза = Неопределено;
    СовпаденийБазы = 0;
    Для Каждого НайденнаяБаза Из Агент.GetInfoBases(Кластер) Цикл
        Если НайденнаяБаза.Name = "УчебнаяБаза85" И НайденнаяБаза.Descr = "syntax-guide85:owned-com" Тогда
            КраткаяБаза = НайденнаяБаза;
            СовпаденийБазы = СовпаденийБазы + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийБазы <> 1 Тогда
        ВызватьИсключение "Не найдена единственная собственная база с точным маркером описания";
    КонецЕсли;
    Каталог = Новый Массив;
    Процесс = Неопределено;
    СовпаденийПроцесса = 0;
    Для Каждого НайденныйПроцесс Из Агент.GetWorkingProcesses(Кластер) Цикл
        Если УчебныйЛокальныйУзел(НайденныйПроцесс.HostName, ЛокальноеИмя)
            И НайденныйПроцесс.MainPort >= 1 И НайденныйПроцесс.MainPort <= 65535
            И НайденныйПроцесс.MainPort = Цел(НайденныйПроцесс.MainPort)
            И НЕ ПустаяСтрока(НайденныйПроцесс.PID) Тогда
            Ключ = Формат(НайденныйПроцесс.MainPort, "ЧГ=0") + "|" + НайденныйПроцесс.PID;
            Каталог.Добавить(Новый Структура("Ключ,Хост", Ключ, НайденныйПроцесс.HostName));
            Если Ключ = КлючПроцесса Тогда
                Процесс = НайденныйПроцесс;
                СовпаденийПроцесса = СовпаденийПроцесса + 1;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    Если ПустаяСтрока(КлючПроцесса) Тогда
        Возврат СериализоватьСвойСнимок(Новый Структура("УчебныеПроцессы", Каталог));
    КонецЕсли;
    Если СовпаденийПроцесса <> 1 Тогда
        ВызватьИсключение "Нужен один живой локальный процесс с ключом из своего каталога";
    КонецЕсли;
    РабочееСоединение = Соединитель.ConnectWorkingProcess("tcp://127.0.0.1:" + Формат(Процесс.MainPort, "ЧГ=0"));
    СовпаденийПолнойБазы = 0;
    Для Каждого НайденнаяПолнаяБаза Из РабочееСоединение.GetInfoBases() Цикл
        Если НайденнаяПолнаяБаза.Name = КраткаяБаза.Name И НайденнаяПолнаяБаза.Descr = КраткаяБаза.Descr Тогда
            СовпаденийПолнойБазы = СовпаденийПолнойБазы + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийПолнойБазы <> 1 Тогда
        ВызватьИсключение "Рабочий процесс не подтвердил свою учебную базу";
    КонецЕсли;
    РабочееСоединение.AddAuthentication(ИмяАдминистратораБазы, ПарольАдминистратораБазы);
    База = Неопределено;
    СовпаденийПослеВхода = 0;
    Для Каждого НайденнаяПослеВхода Из РабочееСоединение.GetInfoBases() Цикл
        Если НайденнаяПослеВхода.Name = "УчебнаяБаза85" И НайденнаяПослеВхода.Descr = "syntax-guide85:owned-com" Тогда
            База = НайденнаяПослеВхода;
            СовпаденийПослеВхода = СовпаденийПослеВхода + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийПослеВхода <> 1 Тогда
        ВызватьИсключение "После аутентификации изменился выбор учебной базы";
    КонецЕсли;
    Снимок = Новый Структура;
    Снимок.Вставить("База", База.Name);
    Снимок.Вставить("ПроцессPID", Процесс.PID);
    Снимок.Вставить("ПортПроцесса", Процесс.MainPort);
    Если База.SecurityProfileName <> "УчебныйПрофиль85" Тогда
        ВызватьИсключение "Своей базе должен быть назначен УчебныйПрофиль85 обычного режима";
    КонецЕсли;
    Профиль = Неопределено;
    СовпаденийПрофиля = 0;
    Для Каждого НайденныйПрофиль Из Агент.GetSecurityProfiles(Кластер) Цикл
        Если НайденныйПрофиль.Name = База.SecurityProfileName
            И НайденныйПрофиль.Descr = "syntax-guide85:owned-com-profile" Тогда
            Профиль = НайденныйПрофиль;
            СовпаденийПрофиля = СовпаденийПрофиля + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийПрофиля <> 1 Тогда
        ВызватьИсключение "Нужен единственный назначенный собственный профиль с точным маркером";
    КонецЕсли;
    Снимок.Вставить("Профиль", Профиль.Name);
    Снимок.Вставить("ОписаниеПрофиля", Профиль.Descr);
    Образец = Неопределено;
    СовпаденийРесурса = 0;
    Для Каждого Ресурс Из Агент.GetSecurityProfileAddIns(Кластер, Профиль.Name) Цикл
        Если Ресурс.Name = "УчебнаяКомпонента85" И Ресурс.Descr = "syntax-guide85:owned-com-resource" Тогда
            Образец = Ресурс;
            СовпаденийРесурса = СовпаденийРесурса + 1;
        КонецЕсли;
    КонецЦикла;
    Если СовпаденийРесурса <> 1 Тогда
        ВызватьИсключение "Подготовьте ровно один свой реальный ресурс с указанным ключом и маркером";
    КонецЕсли;
    Если СтрДлина(Образец.AddInHash) <> 28 Тогда
        ВызватьИсключение "У своего ресурса должна быть настоящая SHA-1/base64 контрольная сумма";
    КонецЕсли;
    БайтыХеша = Base64Значение(Образец.AddInHash);
    Если ТипЗнч(БайтыХеша) <> Тип("ДвоичныеДанные") Тогда
        ВызватьИсключение "Контрольная сумма должна декодироваться в двоичные данные";
    КонецЕсли;
    Если БайтыХеша.Размер() <> 20 ИЛИ Base64Строка(БайтыХеша) <> Образец.AddInHash Тогда
        ВызватьИсключение "Нужны 20 байт SHA-1 в канонической base64-строке";
    КонецЕсли;
    Снимок.Вставить("Name", Образец.Name);
    Снимок.Вставить("AddInHash", Образец.AddInHash);
    Снимок.Вставить("Descr", Образец.Descr);
    Снимок.Вставить("БайтКонтрольнойСуммы", БайтыХеша.Размер());
    Возврат СериализоватьСвойСнимок(Снимок);
КонецФункции

&НаСервереБезКонтекста
Функция СериализоватьСвойСнимок(Снимок)
    Писатель = Новый ЗаписьJSON;
    Писатель.УстановитьСтроку();
    ЗаписатьJSON(Писатель, Снимок);
    Возврат Писатель.Закрыть();
КонецФункции


&НаСервереБезКонтекста
Функция УчебныйЛокальныйУзел(ИмяУзла, ЛокальноеИмя)
    Возврат НРег(ИмяУзла) = ЛокальноеИмя ИЛИ НРег(ИмяУзла) = "localhost" ИЛИ ИмяУзла = "127.0.0.1";
КонецФункции

Разбор по шагам

  1. Проверить имя учебной конфигурации, типы портов и реквизитов до COM. Порты целые в диапазоне 1..65535; секреты не сериализуются.

  2. ConnectAgent обращается только к 127.0.0.1. ConnectionString должна совпасть с построенной строкой без паролей. COM AuthenticateAgent принимает имя, пароль, в отличие от русскоязычного API ras.

  3. Выбрать УчебныйКластер85 по точному имени, локальному хосту и порту менеджера. Отсутствие или неоднозначность не заменяются выбором первого элемента.

  4. Проверить краткое описание УчебнаяБаза85 и точный маркер. Каталог живых локальных процессов позволяет взять настоящий порт|PID, а не подставить 1545 или придуманный PID.

  5. ConnectWorkingProcess использует найденный динамический порт процесса, не порт агента или ras. До аутентификации базы читаются только Name и Descr.

  6. AddAuthentication принимает только имя администратора базы и пароль, не дополнительный аргумент с именем базы. После него заново выбрать свою базу; полные поля читаются только далее.

  7. В конце показать явно перечисленные скалярные поля JSON. После успеха или ошибки очищаются все три пароля и снимается флаг Занято.

  8. После полного выбора собственного стенда проверить назначение обычного профиля, его точное имя и маркер описания. Чужой или неназначенный профиль не принимать.

  9. GetSecurityProfile… вызывается у агента с двумя аргументами: объект своего кластера и строковое имя собственного профиля. Это не русскоязычный метод объекта ras.

  10. Из фактического COMSafeArray взять ровно один ресурс по его реальному ключу и маркеру. Отсутствие/дублирование вызывает явную ошибку, а не создание фиктивного образца.

  11. AddInHash по COM-справке — SHA-1/base64. Чувствителен к регистру base64, не сравнивается через НРег как CLSID.

  12. Строка взята из собственного зарегистрированного ресурса, проверяется в памяти. Файл компоненты не читается и код не подключается.

  13. Правильные 20 байт не доказывают подпись, доверие поставщику или совпадение текущего файла с зарегистрированной суммой.

Как проверить результат

  1. Ресурс найден ровно один раз, его ключ УчебнаяКомпонента85, маркер описания совпадает с подготовленным образцом.

  2. Все поля совпадают с собственной административной настройкой. Значения не заменены примерными CLSID, путём, хешем или командой.

  3. Никакая регистрация, активация ресурса, чтение файла или HTTP-запрос не выполнены; проверка формата не является runtime-проверкой ресурса.

Ожидаемый результат

Прочитано и подробно разобрано действительное описание собственного ресурса без его использования.

На что обратить внимание

  1. COM здесь работает в серверном Windows-процессе. Loopback означает эту машину, не компьютер тонкого клиента; Linux и незарегистрированный соединитель этому уроку не соответствуют.

  2. Присутствие учебных имён и маркера не заменяет права доступа. Не запускайте в рабочем кластере; отделите стенд от production.

  3. Порт агента, порт менеджера кластера, порт ras и динамический порт рабочего процесса — разные значения.

  4. COMSafeArray перечисляется циклом Для Каждого. Это не Массив 1С и не список UUID ras; не приписывайте ему методы или свойства другой коллекции.

  5. Снимки и выбранные процессы могут устареть между запросами. После перезапуска повторите каталог; не пытайтесь автоматически завершить мешающий процесс.

  6. Сырые COM-ошибки могут раскрывать чувствительные сведения. Разбирайте подготовку в отладчике своего стенда, не добавляйте ОписаниеОшибки в публичный JSON.

  7. AddInHash по COM-справке — SHA-1/base64. Чувствителен к регистру base64, не сравнивается через НРег как CLSID.

  8. Строка взята из собственного зарегистрированного ресурса, проверяется в памяти. Файл компоненты не читается и код не подключается.

  9. Правильные 20 байт не доказывают подпись, доверие поставщику или совпадение текущего файла с зарегистрированной суммой.

  10. Глобальный полный доступ профиля и конкретная запись разрешения — разные уровни. Список сам по себе не описывает всю действующую политику.

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

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.