При выполнении регламентных или фоновых заданий в отраслевых конфигурациях 1С (например, Итилиум, решения на базе СЛК, Катран, Guardant) разработчики часто сталкиваются с ошибкой проверки лицензии при программной записи документов. В интерактивном режиме и при отладке через внешнюю обработку запись проходит успешно, однако в фоновом задании возникает исключение:
{ОбщийМодуль.ИТ_ОбщийЗакрытый.Модуль}: Отсутствует ключ защиты конфигурации. Код ошибки 47110
Разберем детально, почему возникает данная ситуация в серверном контексте и какими способами можно устранить сбой.
Проанализируем специфику выполнения серверного кода в сеансах регламентных заданий:
ПередНачаломРаботыСистемы и ПриНачалеРаботыСистемы. Если подключение к серверу лицензирования и захват лицензии отраслевой защиты прописаны в этих модулях, фоновый сеанс запускается без инициализированного контекста защиты.rphost от имени системной учетной записи (например, USR1CV8). Настройки подключения к СЛК могут быть сохранены в профиле конкретного пользователя ОС, к которому у службы сервера нет доступа.ПередЗаписью или ПриЗаписи объекта часто располагаются обращения к защищенным закрытым функциям (например, расчет параметров или контрольные проверки), требующим активного подключения к ключу защиты.Если в рамках фонового задания выполняется сугубо служебная модификация реквизитов (например, простановка меток, выгрузка данных, служебные комментарии) и пересчет отраслевых данных не требуется, вызов закрытого модуля можно отключить с помощью режима загрузки.
В типовых механизмах платформы 1С для отключения проверок при записи используется свойство ОбменДанными.Загрузка = Истина. Однако в некоторых конфигурациях (например, в ряде версий Итилиум) разработчики используют собственные флаги на уровне объекта или дополнительных свойств, такие как мЗагрузкаДанных.
Посмотрим на пример кода с правильной установкой режима загрузки:
ОбъектИнцидент = ВыборкаДетальныеЗаписи.Инцидент.ПолучитьОбъект();
ИНН = ВыбратьИННИзОписания(ОбъектИнцидент);
Если ЗначениеЗаполнено(ИНН) Тогда
Попытка
НачатьТранзакцию();
ОбъектИнцидент.Описание = ОбъектИнцидент.Описание + Символы.ПС + "//>" + ТекущаяДата();
// Устанавливаем типовой флаг загрузки данных платформы
ОбъектИнцидент.ОбменДанными.Загрузка = Истина;
// Для отраслевых конфигураций устанавливаем внутренний флаг пропуска проверок, если он предусмотрен
// Например, в конфигурации Итилиум:
// ОбъектИнцидент.мЗагрузкаДанных = Истина;
ОбъектИнцидент.Записать(РежимЗаписиДокумента.Запись);
Текст = Новый ЗаписьТекста(ИмяФайлаВыгрузкиИНН, КодировкаТекста.ANSI, , Истина);
Текст.ЗаписатьСтроку(Строка(ИНН));
Текст.Закрыть();
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ЗаписьЖурналаРегистрации(
"РегламентноеЗадание.ВыгрузкаИНН",
УровеньЖурналаРегистрации.Ошибка,
,
,
ОписаниеОшибки()
);
КонецПопытки;
КонецЕсли;
Если конфигурация находится на поддержке с возможностью изменения, в самом обработчике ПриЗаписи можно обернуть вызов защищенного метода в блок Попытка ... Исключение, чтобы ошибка ключа не прерывала служебную транзакцию:
Попытка
ИТ_ОбщийЗакрытый.оз_ФункцияРасчетаПараметров13(Ссылка);
Исключение
// Запись предупреждения в журнал регистрации при отсутствии ключа в фоновом режиме
ЗаписьЖурналаРегистрации("ЗащитаКонфигурации", УровеньЖурналаРегистрации.Предупреждение,,, ОписаниеОшибки());
КонецПопытки;
Если для логики регламентного задания критически важно корректное выполнение функций из закрытого модуля, необходимо явно инициализировать защиту в начале сеанса фонового задания.
УстановкаПараметровСеанса модуля сеанса. Это гарантирует готовность подсистемы защиты для сеансов любого типа, включая регламентные.Рассмотрим пример проверки инициализации в процедуре регламентного задания:
Процедура ВыполнитьРегламентнуюОбработку() Экспорт
// Явная инициализация подсистемы защиты для фонового сеанса
// Имя метода зависит от используемой конфигурации и СЛК
Если Не ИТ_ОбщийМодульЗащиты.ИнициализироватьЗащиту() Тогда
ВызватьИсключение "Не удалось получить лицензию отраслевой защиты в фоновом задании.";
КонецЕсли;
// Основная логика обработки данных
// ...
КонецПроцедуры
Если программная инициализация не дает результата, проанализируем настройки окружения операционной системы:
ProgramData / CommonAppData), а не только в локальном профиле пользователя, под которым запускался конфигуратор.USR1CV8), имеет права на чтение файлов ключей, лицензий и каталогов с внешними компонентами защиты.