При обновлении классических конфигураций на «обычных» формах, таких как Управление торговлей 10.3, специалисты нередко сталкиваются с внезапным закрытием программы. Ситуация выглядит следующим образом: процесс обновления метаданных в конфигураторе проходит успешно, однако при первом запуске в режиме «Предприятие» для выполнения обработок обновления система выдает стандартное окно Windows об ошибке приложения и закрывается. В этой статье мы подробно разберем, почему это происходит и как довести обновление до конца.
Рассмотрим конкретную ситуацию. При переходе с версии 10.3.49.1 на 10.3.49.4 в окне сообщений могут появиться записи о выполненных этапах, причем иногда в странном порядке:
После этого работа программы аварийно завершается. Чтобы понять причину, воспользуемся отладчиком. Проанализируем процедуру ОбновитьИнформационнуюБазу, которая находится в общем модуле ОбновлениеИнформационнойБазыКлиент. Выясняется, что критическая ошибка происходит при выполнении оператора ОбновитьИнтерфейс();.
Проблема кроется в особенностях работы платформы 1С:Предприятие 8.3 с конфигурациями, использующими «Обычное приложение». Метод ОбновитьИнтерфейс() (или его англоязычный аналог RefreshInterface()) предназначен для перерисовки главного меню, командных панелей и других элементов интерфейса после внесения изменений в структуру прав или состав подсистем.
Начиная с версий платформы 8.3.12 и 8.3.13, разработчики 1С внесли значительные изменения в механизмы отрисовки графического интерфейса, оптимизируя их под управляемые формы и интерфейс «Такси». К сожалению, это привело к возникновению багов совместимости со старым движком отрисовки. Когда платформа пытается перестроить дерево меню в обычном приложении, происходит некорректное обращение к памяти (Access Violation), и операционная система принудительно закрывает процесс 1cv8.exe.
Как показывает практика, самым быстрым и эффективным решением является временный или постоянный переход на ту версию платформы, где работа с обычными формами еще не была нарушена. Проанализируем опыт коллег: использование версии 8.3.8.1964 позволяет успешно завершить процедуру обновления без вылетов.
Рассмотрим шаги по реализации этого решения:
8.3.8.хххх или стабильную версию из ветки 8.3.10.ОбновитьИнтерфейс() отработает корректно, и все регламентные процедуры обновления завершатся успешно.Если по каким-то причинам сменить платформу невозможно (например, из-за жестких требований других конфигураций на сервере), мы можем вмешаться в код конфигурации. Разберем, как это сделать правильно. Нам необходимо временно нейтрализовать вызов проблемного метода.
Найдем в общем модуле ОбновлениеИнформационнойБазыКлиент соответствующую строку и воспользуемся конструкцией Попытка ... Исключение. Это позволит программе проигнорировать ошибку отрисовки и продолжить работу.
// В процедуре ОбновитьИнформационнуюБазу()
Попытка
ОбновитьИнтерфейс();
Исключение
// Игнорируем ошибку отрисовки интерфейса,
// так как она не влияет на логику данных
ЗаписьЖурналаРегистрации("ОбновлениеИнтерфейса", УровеньЖурналаРегистрации.Предупреждение, , , "Ошибка при обновлении интерфейса пропущена.");
КонецПопытки;
После того как обновление будет полностью завершено, этот блок кода можно оставить (он не нанесет вреда) или вернуть в исходное состояние. Важно понимать, что при следующем нормальном запуске системы интерфейс обновится автоматически из кэша метаданных.
Интересной особенностью данной ошибки является её зависимость от разрядности приложения. Замечено, что 64-битный клиент (x86-64) платформы 8.3 чаще подвержен падениям при работе с методом ОбновитьИнтерфейс() в старых конфигурациях. Если вы используете 64-битную версию, попробуйте выполнить обновление через 32-битный толстый клиент той же самой сборки платформы. В многих случаях это решает проблему без изменения кода или отката на старые релизы.
Иногда вылет провоцируется не только багом платформы, но и накопленными ошибками в локальном кэше метаданных. Перед началом обновления выполним следующие действия:
%AppData%\1C\1cv8 и %LocalAppData%\1C\1cv8.Это исключит ситуацию, когда платформа пытается отрисовать интерфейс, опираясь на устаревшие или поврежденные индексные файлы форм.
Мы выяснили, что ошибка при обновлении УТ 10.3 на современных версиях платформы 8.3 связана с техническим несовершенством метода ОбновитьИнтерфейс() в режиме обычного приложения. Для успешного решения проблемы мы рекомендуем:
Попытка ... Исключение.Соблюдение этих правил позволит вам избежать критических сбоев и корректно обновлять старые конфигурации, сохраняя работоспособность системы.