В практике поддержки и администрирования старых систем на платформе 1С:Предприятие 7.7 (особенно работающих в связке с Microsoft SQL Server) иногда возникает крайне загадочная ситуация. Вы вносите изменения в форму или модуль документа, сохраняете конфигурацию, но на некоторых рабочих станциях пользователи продолжают видеть старую версию формы. Более того, при попытке отладки на таких компьютерах может возникать «фантомное» поведение системы: например, отладчик прерывает работу на пустой строке с ошибкой деления на ноль, хотя визуально в конфигураторе в этой строке нет никакого кода.
В рамках этой статьи мы подробно разберем, почему возникает этот сбой, как устроена технология динамического обновления метаданных без монопольного доступа, почему современные операционные системы блокируют работу внешних библиотек и как исправить рассинхронизацию кода по шагам.
Если на одном компьютере загружается измененная форма, а на другом — старая версия из конфигурации, и это поведение не зависит от имени пользователя 1С, то в системе гарантированно используется механизм динамической подмены метаданных. В среде разработчиков 1С 7.7 самым популярным инструментом для решения этой задачи является внешняя компонента TurboMD.dll.
Давайте проанализируем, как устроен этот механизм. Компонента TurboMD перехватывает обращения платформы к файлу конфигурации 1cv7.md. Вместо чтения диалогов и модулей форм из основного файла метаданных, библиотека считывает их из внешних текстовых файлов, список которых жестко задается в конфигурационном файле turbomd.prm. Этот файл располагается в каталоге базы данных и содержит строки сопоставления объектов метаданных и физических файлов на диске.
Когда программист вносит изменения, он выгружает форму во внешний файл (например, с помощью утилит OpenConf), и пользователи мгновенно видят обновления без необходимости перезапускать сеансы или монопольно выгонять коллег из базы. Однако, если на конкретном компьютере эта компонента по какой-то причине не смогла запуститься, платформа 1С 7.7 возвращается к стандартному поведению — она считывает конфигурацию напрямую из файла 1cv7.md, где записана старая (или неактуальная) версия формы. Именно из-за этого возникает ситуация, когда на разных компьютерах отображаются разные интерфейсы.
Выясним причину, почему компонента отказывается работать на некоторых компьютерах. Как правило, «проблемными» оказываются рабочие станции, на которых установлены современные операционные системы (Windows 10 или Windows 11). При запуске 1С в таких операционных системах в системном журнале или окне сообщений может появляться незаметная на первый взгляд ошибка:
«Ошибка при создании объекта из компоненты [Путь]\turbomd.dll (отсутствует CLSID)»
Поскольку любая внешняя компонента для платформы 1С 7.7 представляет собой COM-сервер, при первом вызове через функцию ЗагрузитьВнешнююКомпоненту() платформа пытается зарегистрировать библиотеку в системном реестре Windows. Начиная с Windows Vista и Windows 7, в операционных системах Microsoft по умолчанию включена система контроля учетных записей (UAC). Обычный пользователь без прав локального администратора не имеет доступа на запись в системные ветки реестра (такие как HKEY_CLASSES_ROOT), из-за чего автоматическая регистрация библиотеки завершается неудачей. Компонента не загружается, и пользователь видит старый код напрямую из MD-файла.
Для исправления этой ошибки выполним одно из следующих действий:
turbomd.dll в реестре. После этого программу можно запускать в обычном режиме под стандартным пользователем.
regsvr32.exe "C:\PathToYourBase\turbomd.dll"
(вместо пути подставьте фактическое расположение файла библиотеки в каталоге вашей информационной базы).Посмотрим на ситуацию, когда отладчик ведет себя неадекватно: вы установили точку останова на исполняемом коде, пошагово доходите до пустой строки 80 (где нет никакого кода), нажимаете клавишу F8 — и система аварийно завершает работу с ошибкой деления на ноль. При этом в конфигураторе вы четко видите, что никакого деления в этой строке нет.
Это классический пример рассинхронизации исходного кода, вызванный использованием TurboMD. Давайте разберем по шагам, почему это происходит:
1cv7.md. Для отладчика строка 80 действительно является пустой.turbomd.dll выполняется код из внешнего файла, прописанного в turbomd.prm.Чтобы устранить эту проблему, необходимо синхронизировать код во внешних файлах и в файле конфигурации MD.
Для эффективной и безопасной разработки в среде 1С 7.7 с использованием динамической подмены кода мы рекомендуем использовать связку инструментов TurboMD и программного расширения конфигуратора OpenConf. Рассмотрим правильную последовательность действий при разработке:
turbomd.prm. Вы мгновенно видите изменения в режиме «Предприятие» без сохранения конфигурации.1cv7.md.Для того чтобы избежать ситуаций, когда старые файлы настроек TurboMD годами лежат в базе данных и перекрывают новые изменения, внесенные другими программистами напрямую в MD-файл, внедрим защитный механизм в модуль приложения.
Откроем глобальный модуль конфигурации и в процедуру ПриНачалеРаботыСистемы() добавим программный код, который будет автоматически деактивировать файл динамических настроек, если дата изменения конфигурационного файла 1cv7.md окажется новее, чем зафиксированная контрольная дата:
Процедура ПриНачалеРаботыСистемы()
// [Ваш стандартный код инициализации системы]
// Автоматический контроль актуальности файлов конфигурации и отключение TurboMD
ВремяМД = "";
ФС.АтрибутыФайла(КаталогИБ() + "1cv7.md", , , , , ВремяМД);
ВремяКонтрольное = СокрЛП(Константа.ДатаПоследнегоИзмененияКонфигурации);
Если ВремяМД > ВремяКонтрольное Тогда
Если ФС.СуществуетФайл(КаталогИБ() + "TurboMD.prm") = 1 Тогда
Размер = 0;
ФС.АтрибутыФайла(КаталогИБ() + "TurboMD.prm", Размер);
Если Размер > 0 Тогда
// Переименовываем файл настроек, чтобы отключить динамическую подмену модулей
ФС.ПереименоватьФайл(КаталогИБ() + "TurboMD.prm", КаталогИБ() + "TurboMD.prm~", 1);
Сообщить("Внимание! Обнаружена новая версия конфигурации. Файл динамической отладки TurboMD отключен.");
КонецЕсли;
КонецЕсли;
Константа.ДатаПоследнегоИзмененияКонфигурации = ВремяМД;
КонецЕсли;
КонецПроцедуры
Для реализации этого алгоритма вам потребуется завести в метаданных периодическую или простую константу ДатаПоследнегоИзмененияКонфигурации с типом данных «Строка». Этот простой механизм застрахует команду разработки от случайных наложений старого отладочного кода на новые рабочие релизы конфигурации.