При разработке расширений для конфигураций на базе Библиотеки стандартных подсистем (БСП) программисты часто сталкиваются с ситуацией, когда доработки в расширении прекрасно функционируют в обычном режиме (например, при вызове из внешней обработки), но полностью игнорируются системой в процессе обновления информационной базы (при запуске с параметром ЗапуститьОбновлениеИнформационнойБазы). Рассмотрим подробно, почему это происходит и как заставить расширение работать в контексте процедур обновления.
Разберем ситуацию: мы добавили в расширение общий модуль УправлениеДоступомПереопределяемый и перехватили процедуру ПриЗаполненииПоставляемыхПрофилейГруппДоступа с помощью аннотации &После. Наша задача — добавить новую роль из расширения в стандартный профиль. Однако при запуске обновления точка останова в типовом коде срабатывает, а в коде расширения — нет. Проанализируем основные причины этого явления.
Процесс обновления информационной базы в современных конфигурациях часто выполняется в контексте фонового задания. Это критический момент, так как сеанс фонового задания может инициализироваться иначе, чем обычный пользовательский сеанс. Выясним, почему это важно:
Используется в фоновых заданиях. Если флаг снят, код расширения просто не будет загружен в поток выполнения фонового задания.Для диагностики в файловом варианте базы попробуем принудительно отключить фоновое выполнение процедур обновления, чтобы код гарантированно выполнялся в основном потоке. Это позволит исключить проблему разделения сеансов.
Одной из наиболее вероятных причин игнорирования расширения является работа системы под определенным профилем безопасности. Посмотрим на важные настройки в консоли администрирования серверов 1С:
Даже если в самом расширении снята галочка Безопасный режим, платформа может блокировать выполнение кода расширения, если в профиле безопасности сервера не разрешено использование расширений или ограничены права на работу с определенными ресурсами. Проанализируем состояние настройки "Профили безопасности" в консоли кластера. Если профиль назначен, необходимо убедиться, что в нем установлены все необходимые разрешения для работы расширений конфигурации.
В файловых базах также стоит проверить программную установку безопасного режима. Если БСП внутри процедур обновления вызывает УстановитьБезопасныйРежим(Истина), это может накладывать ограничения на вызов методов из «недоверенных» расширений в зависимости от версии платформы.
Версия платформы 8.3.12 имеет свои особенности работы с механизмом расширений. Рассмотрим влияние режима совместимости. Если в основной конфигурации и в расширении установлен режим Не использовать, это требует от разработчика строгой идентичности сигнатур методов.
Проверим правильность написания аннотации и процедуры. Рекомендуется всегда использовать префикс расширения для имен процедур-перехватчиков, чтобы избежать конфликтов имен:
&После("ПриЗаполненииПоставляемыхПрофилейГруппДоступа")
Процедура Расш1_ПриЗаполненииПоставляемыхПрофилейГруппДоступа(ОписанияПрофилей, ПараметрыОбновления) Экспорт
// Наш код добавления роли
НоваяРоль = "Расш1_Роль1";
// Проверка существования профиля в коллекции
Если ОписанияПрофилей.Количество() > 1 Тогда
ОписанияПрофилей[1].Роли.Добавить(НоваяРоль);
КонецЕсли;
КонецПроцедуры
Важно помнить, что на платформе 8.3.12 механизм &После в общих модулях может не срабатывать, если вызов целевой процедуры происходит через методы Выполнить() или Вычислить(), которые иногда используются в ядре БСП для динамического вызова переопределяемых модулей.
Процедура ПриЗаполненииПоставляемыхПрофилейГруппДоступа работает с объектами метаданных. Если вы пытаетесь добавить роль, которая существует только в расширении, БСП может её "не увидеть". Разберем по шагам механизм регистрации:
Идентификаторы объектов метаданных, попытка обращения к ним в системных процедурах может игнорироваться или вызывать скрытую ошибку.Выясним причину, связанную с моментом подключения расширений. При запуске с флагом ЗапуститьОбновлениеИнформационнойБазы, система проходит через этапы инициализации. В некоторых случаях (особенно в старых версиях платформы) процедуры обновления могут вызываться до того, как платформа полностью инициализирует все расширения метаданных.
Посмотрим на пример того, как можно проверить, "видит" ли система расширение в момент выполнения кода. Добавим в начало типовой процедуры следующий отладочный код:
Для Каждого Расширение Из РасширенияКонфигурации.Получить() Цикл
ЗаписьЖурналаРегистрации("ТестРасширения", УровеньЖурналаРегистрации.Информация, , ,
"Расширение: " + Расширение.Имя + ", Состояние: " + Расширение.Активно);
КонецЦикла;
Если в журнале регистрации при запуске обновления вы не видите своего расширения или оно находится в состоянии Активно = Ложь, значит, проблема в механизме подключения расширения на ранних этапах старта.
Если &После упорно игнорируется, проанализируем возможность использования аннотации &Вместо. Это более "жесткий" способ перехвата управления, который позволяет гарантированно войти в контекст расширения. При этом крайне важно вызвать основной код, чтобы не нарушить логику БСП.
&Вместо("ПриЗаполненииПоставляемыхПрофилейГруппДоступа")
Процедура Расш1_ПриЗаполненииПоставляемыхПрофилейГруппДоступа(ОписанияПрофилей, ПараметрыОбновления) Экспорт
// Вызов основной логики типового модуля
ПродолжитьВызов(ОписанияПрофилей, ПараметрыОбновления);
// Наша доработка после выполнения основного кода
// Добавляем роль в нужный профиль
Для Каждого ОписаниеПрофиля Из ОписанияПрофилей Цикл
Если ОписаниеПрофиля.Имя = "Администратор" Тогда
ОписаниеПрофиля.Роли.Добавить("Расш1_Роль1");
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Использование ПродолжитьВызов() обеспечивает выполнение оригинальной процедуры, а ваш код сработает как аналог &После, но с более высоким приоритетом инициализации в стеке вызовов.
Подводя итог, проанализируем контрольный список действий, если ваше расширение не работает при обновлении:
&После на &Вместо с обязательным вызовом ПродолжитьВызов().Следуя этим шагам, мы сможем локализовать причину и обеспечить корректную работу расширения в любых режимах запуска системы.