При обслуживании файловых баз 1С:Предприятия 7.7 администраторы и программисты регулярно сталкиваются с проблемой: для проведения регламентных процедур (реиндексация, тестирование и исправление, обновление конфигурации) требуется монопольный вход, однако в базе остаются висеть сеансы пользователей. Сотрудники могут уйти домой, оставив программу открытой, либо сеанс может зависнуть на уровне сети из-за некорректного выключения клиентского компьютера.
Выясним причину такого поведения, проанализируем ограничения файловой архитектуры 1С 7.7 и рассмотрим основные способы корректного и принудительного завершения сеансов.
В файловой версии 1С 7.7 отсутствует выделенный сервер приложений, который мог бы централизованно управлять сеансами и отключать клиентов по команде администратора. Блокировка таблиц (файлов .dbf и .cdx) осуществляется на уровне файловой системы операционной системы, а факт присутствия пользователя в каталоге фиксируется файлами блокировок *.lck в подкаталогах пользователей.
Если хотя бы один клиентский процесс держит дескриптор открытого файла базы данных через локальную сеть или терминальную сессию, попытка монопольного входа завершится ошибкой. Разберем по шагам, как можно освободить базу данных штатными и административными методами.
Рассмотрим классический программный механизм оповещения и закрытия запущенных копий 1С. В конфигурации создается периодический опрос специальной константы или внешнего файла-флага. Если флаг взведен, запускается таймер обратного отсчета, после чего вызывается штатная функция завершения работы программы.
Разберем реализацию данного способа по шагам:
ДоЗавершенияРаботы или БлокировкаСеансов.Посмотрим на пример кода в глобальном модуле конфигурации:
Перем глПериодОпроса, глОсталосьДоВыхода;
Процедура ОпросСостоянияСистемы() Экспорт
Если Константа.ДоЗавершенияРаботы > 0 Тогда
Если глОсталосьДоВыхода = 0 Тогда
глОсталосьДоВыхода = Константа.ДоЗавершенияРаботы * 60;
Предупреждение("Внимание! Через " + СокрЛП(Константа.ДоЗавершенияРаботы) + " мин. база будет закрыта для обслуживания!" + РазделительСтрок + "Пожалуйста, сохраните работу.", 10);
Иначе
глОсталосьДоВыхода = глОсталосьДоВыхода - глПериодОпроса;
Если глОсталосьДоВыхода <= 0 Тогда
ЗавершитьРаботуСистемы(0); // 0 - завершение без подтверждения сохранения
КонецЕсли;
КонецЕсли;
Иначе
глОсталосьДоВыхода = 0;
КонецЕсли;
КонецПроцедуры
Процедура ПриНачалеРаботыСистемы()
глПериодОпроса = 30; // интервал проверки в секундах
глОсталосьДоВыхода = 0;
// Запрет входа обычным пользователям, если база заблокирована
Если Константа.ДоЗавершенияРаботы > 0 Тогда
Если ВРег(СокрЛП(ИмяПользователя)) <> "АДМИНИСТРАТОР" Тогда
Предупреждение("База находится в режиме подготовки к обслуживанию. Вход запрещен!", 5);
СтатусВозврата(0);
Возврат;
КонецЕсли;
КонецЕсли;
ОбработкаОжидания("ОпросСостоянияСистемы", глПериодОпроса);
КонецПроцедуры
Важная особенность метода ЗавершитьРаботуСистемы(0): параметр со значением 0 отключает вывод диалоговых окон с вопросом о сохранении измененных объектов. Однако встроенный механизм ОбработкаОжидания полностью останавливает выполнение, если у пользователя открыто любое модальное окно (например, системное предупреждение, диалог выбора периода или модальная форма документа). В таком случае программный метод не сработает, и потребуется вмешательство на уровне операционной системы.
Если пользователи работают на терминальном сервере (RDP) или если необходимо точечно найти процессы, блокирующие файлы базы, применим системный сценарий с использованием системных утилит командной строки.
Проанализируем пакетный скрипт автоматического закрытия процессов, удерживающих файлы *.lck или файлы базы данных:
HANDLE.EXE C:\Bases\Trade\*.lck > C:\Temp\locks.txt
FOR /F "skip=5 tokens=2,3" %%i in (C:\Temp\locks.txt) do TASKKILL /PID %%j /T /F
DEL /Q C:\Temp\locks.txt
Разберем логику работы скрипта: утилита handle.exe сканирует каталог базы данных и определяет идентификаторы процессов (PID), которые держат открытые файловые дескрипторы. Затем команда taskkill принудительно (с флагом /F) снимает эти процессы вместе с дочерними ветками (флаг /T).
В ситуации, когда база расположена на файловом сервере в локальной сети (без терминального сервера), а пользователи работают с клиентских ПК, принудительно освободить файлы можно несколькими путями:
fsmgmt.msc на сервере, переходим в раздел «Открытые файлы» и принудительно закрываем дескрипторы нужного каталога либо в разделе «Сеансы» отключаем конкретных пользователей.
net session \\ИмяКомпьютераКлиента /delete
openfiles /disconnect /a *
icacls). Все сетевые клиенты мгновенно теряют соединение, а блокировочные файлы *.lck перестают удерживаться операционной системой и могут быть перезаписаны при следующем старте.Если работа организована через терминальный сервер, зависания чаще всего происходят из-за того, что пользователи закрывают окно RDP «крестиком», оставляя сессию в состоянии «Отключено» (Disconnected). Для исключения подобных ситуаций настроим политики таймаутов:
Конфигурация компьютера -> Административные шаблоны -> Компоненты Windows -> Службы удаленных рабочих столов -> Узел сеансов удаленных рабочих столов -> Ограничения по времени сеанса.qwinsta (просмотр сеансов) и rwinsta [ID] или logoff [ID] (завершение сеанса).Для регулярного ночного монопольного обслуживания базы (реиндексация, пакетная выгрузка) оптимально комбинировать оба подхода:
net session или openfiles, очищает временные каталоги и запускает конфигуратор 1С 7.7 в пакетном режиме с ключом монопольного доступа /M.