Досталось мне по наследству выполнение обновления баз 1С Бухгалтерии 3 в количестве 100 шт и ЗУП 3 - 100 шт(измененные, но не сильно. Обновлять только из хранилища). У нас конечно написана конфа по обслуживанию такого количества баз и даже пакетное обновление реализовано, в том числе и из хранилища для измененных конфигураций, но ... все этапы этого варианта обновления заточены на участие Админа.
Как это было реализовано до меня
1) Сначала надо зайти на сервер и завершить все сеансы оставленные пользователями.
2) Запустить написанную предшественниками не знаю на чем программку по блокировке регламентных заданий на сервере
3) Скачать новый *.cfu файл обновления для типовых баз
3а) Обновить изменную базу в хранилище из скачанного cfu файла
4) Сформировать пакетные bat файлы (обычно делим на 4 потока - 4 файла)
5) Запустить пакетные файлы и дождаться их завершения.
6) Запустить каждый экземпляр базы в режиме Предприятия, подтвердить легальность и закрыть базу.
7) Запустить программку по разблокировке регламентных заданий.
Готово !!! Мы провели незабываемое время у компа и обновили 80 типовых баз, потратив на это все выходные.
Проделав дважды такую операцию, мне стало грустно и начал искать пути полной автоматизации этого процесса. В итоге было обнаружено пару достойных наработок по пакетному обновлению в открытом доступе и начался процесс их переработки и адаптации под мои нужды. Но у всех найденных вариантов был один существенный недостаток - подтвердить легальность и закончить обновление они не могли. Поэтому моя задача не автоматизируется на 100 % без этого.
Начал изучать механизм завершения обновления через отладчик и искать пути решения моей задачи. В итоге были найдены точки перехвата событий при первом открытии обновленной конфигурации и мои труды и старания вылились в расширение для конфигурации, которое умеет само подтверждать легальность обновления, дожидаться выполнения обработчиков и закрывать 1с Предприятие. Выполнено это в виде расширения что бы не вскрывать типовые БУХи . Со вскрытой конфигурацией, в частности ЗУП 3, это расширение тоже работает, т.к. используются точки входа и выхода типовых процедур.
В итоге, собрав все в одну разработку и дополнив ее механизмом отрубания пользователей от текущей базы через COM соединение с агентом сервера 1С перед стартом обновления, получил полностью 100% автоматический механизм обновления типовых баз 1С.
Теперь процесс обновления выглядит так
1) В обработке обновления выбираем тип базы ( Бухгалтерия ) и номер потока (все базы в конфе обслуживания уже поделены на потоки )
2) Нажимаем кнопку "Выполнить"
и ... ложимся спать. Все базы выбранного потока обновлены, Легальность обновления подтверждена, Обработчики обновления выполнены.
Что делает обработка автоматически сама:
1) Определяет текущий релиз базы
2) Скачивает с сайта 1с файл с информацией об обновлении данного типа конфигурации. (Бух, ЗУП, УТ...)
3) Проверяет наличие в каталоге конфигураций доступного обновления из списка.
4) Если нужного обновления нет, скачивает его автоматически с сайта 1С (нужен логин и пароль для доступа на сайт 1С) и размещает его в каталог обновлений.
5) Отрубает на сервере 1С все сеансы пользователей от текущей базы
6) Запускает обновление конфигурации и базы данных.
7) Если обновились до последнего релиза и больше обновлять не надо, запускает 1С в режиме Предприятия для подтверждения легальности обновления и выполнения отложенных обработчиков обновления
и так по кругу пока не кончится список баз.
Расширение подтверждения легальности протестировано на БП 3 релиз 3.0.69.32 , ЗУП 3 релиз 3.1.9.159 работающих на MS-SQL сервере. Для файловых вариантов баз тоже должно работать, но мною не тестировалось, т.к. у нас таких баз нет.
Не сомневаюсь что для Торговли, Розницы и других типовых конфигураций от 1С это расширение будет работать.
Дополнительно прилагаю модуль обработки по автоматическому обновлению информационных баз, в котором реализованы все вышеописанные автоматические процедуры обновления. Его с легкостью можно адаптировать под собственные нужды и вариант работы (только для программистов) т.к. написан на родном языке 1С.
Данная обработка работает в самописной конфигурации по обслуживанию информационных баз.
P.S. Да я знаю про "Обновлятор". В бесплатной версии он не работает с таким количеством баз, были мысли приобрести полную версию, но было интересно решить данную задачу самому, т.к. половина функционала уже было в нашей базе обслуживания.
UPDATE лето 2021
Подняли свою автоматизацию обновления на новый уровень. Создали регламентное задание из этого модуля обновления, теперь даже запускать ничего не надо, все работает само. Разделили ВСЕ базы на 7 потоков (БП 3 и ЗУП3.1 обновляются с Пн по Пт, В субботу обновляются БП КОРП , в воскресенье БП Сельхозка). На полуавтомате остались тока БП с дописками и обновлением из хранилища.
Кусок основного кода из обработки обновления
// Прверка наличия обновлений
МассивОбновлений = ВыполнитьЗагрузкуСпискаОбновлений(ПараметрыComБазы.ТекущаяВерсия);
Если МассивОбновлений = Неопределено Тогда
Возврат;
КонецЕсли;
КоличествоДоступныхОбновлений = МассивОбновлений.Количество();
Если КоличествоДоступныхОбновлений = 0 Тогда
Если ОбновлениеБыло Тогда
СообщитьПользователю(НСтр("ru = 'Обработчики обновления информационной базы.'"));
КомандаПакетногоОбновления = СтрШаблон("""%1"" ENTERPRISE %2 /RunModeManagedApplication",
ПараметрыComБазы.ПутьКПлатформе, СтрокаСоединения);
ЗапуститьПриложение(КомандаПакетногоОбновления, , Истина, КодВозврата);
Если КодВозврата = 0 Тогда
СообщитьПользователю(НСтр("ru = 'Обработчики выполнены.'"));
Иначе
СообщитьПользователю(НСтр("ru = 'Ошибка при выполнении обработчиков.'"));
// Возврат;
КонецЕсли;
КонецЕсли;
СообщитьПользователю(СтрШаблон(НСтр("ru = 'Текущая версия: %1. Обновление не требуется.'"), ПараметрыComБазы.ТекущаяВерсия));
Прервать;
КонецЕсли;
ЗагруженноеОбновлениеНайдено = Ложь;
Для Сч = 1 По КоличествоДоступныхОбновлений Цикл
ВерсияДляОбновления = МассивОбновлений[КоличествоДоступныхОбновлений - Сч];
ФайлОбновленияВерсии = СтрШаблон("%1\%2\%3\1cv8.cfu", ПараметрыОбновления.КаталогФайловОбновления, ТипКонфигурации, ВерсияДляОбновления.Версия);
ФайлОбновленияВерсииОбъект = Новый Файл(ФайлОбновленияВерсии);
Если ФайлОбновленияВерсииОбъект.Существует() Тогда
ЗагруженноеОбновлениеНайдено = Истина;
СообщитьПользователю(СтрШаблон(НСтр("ru = 'Текущая версия: %1. Доступна для обновления версия: %2.'"),
ПараметрыComБазы.ТекущаяВерсия, ВерсияДляОбновления.Версия));
Прервать;
КонецЕсли;
КонецЦикла;
// Загрузка файлов обновления
Если Не ЗагруженноеОбновлениеНайдено Тогда
ВерсияДляОбновления = МассивОбновлений[КоличествоДоступныхОбновлений - 1];
ФайлОбновленияВерсии = СтрШаблон("%1\%2\%3\1cv8.cfu", ПараметрыОбновления.КаталогФайловОбновления, ТипКонфигурации, ВерсияДляОбновления.Версия);
СообщитьПользователю(СтрШаблон(НСтр("ru = 'Текущая версия: %1. Доступна для загрузки версия: %2 (Поставщик %3, размер %4).'"),
ПараметрыComБазы.ТекущаяВерсия, ВерсияДляОбновления.Версия, ВерсияДляОбновления.Поставщик, ВерсияДляОбновления.РазмерФайлаОбновления));
Если НЕ ПолучитьФайлыОбновлений(ТипКонфигурации, ВерсияДляОбновления) Тогда
Возврат;
КонецЕсли;
КонецЕсли;
// Отрубим сеансы пользователей для серверной базы
Если ПараметрыПодключения.ВариантРаботыИнформационнойБазы = 1 Тогда
Попытка
СообщитьПользователю(НСтр("ru = 'Отрубаем все сеансы пользователей с информационной базой.'"));
Коннектор = Новый COMОбъект("v83.COMConnector");
Если СтрНайти(ИмяСервера1СПредприятия,":")>0 Тогда // Если используется не стандартный порт 1541 или он передан в имени сервера, то в номере порта "1" надо заменить на "0"
Конект = Лев(ИмяСервера1СПредприятия,СтрДлина(ИмяСервера1СПредприятия)-1) + "0";
Иначе
Конект = строка(ИмяСервера1СПредприятия);
КонецЕсли;
Агент = Коннектор.ConnectAgent(Конект);
Кластеры = Агент.GetClusters();
Для каждого Кластер из Кластеры Цикл
Агент.Authenticate(Кластер,,);
Процессы = Агент.GetWorkingProcesses(Кластер);
.......
.......
// Создание резервной копии выгрузкой DT
// В нашем варианте нет смысла в использовании
//СообщитьПользователю(СтрШаблон(НСтр("ru = 'Создание резервной копии информационной базы (%1).'"), ИмяВременногоФайла));
//КомандаПакетногоАрхивирования = СтрШаблон("""%1"" CONFIG %2 /DumpIB %3 /OUT %4 -NoTruncate",
//ПараметрыComБазы.ПутьКПлатформе, СтрокаСоединения, СтрокаДампа, СтрокаЛогов);
//ЗапуститьПриложение(КомандаПакетногоАрхивирования, , Истина, КодВозврата);
//Если КодВозврата = 0 Тогда
// СообщитьПользователю(НСтр("ru = 'Резервная копия информационной базы успешно создана.'"));
//Иначе
// СообщитьПользователю(НСтр("ru = 'Ошибка при создании резервной копии информационной базы.'"));
// Возврат;
//КонецЕсли;
// Обновление информационной базы
СообщитьПользователю(НСтр("ru = 'Обновление информационной базы.'"));
КомандаПакетногоОбновления = СтрШаблон("""%1"" CONFIG %2 /UpdateCfg ""%3"" /UpdateDBCfg /DisableStartupMessages /OUT %4 -NoTruncate",
ПараметрыComБазы.ПутьКПлатформе, СтрокаСоединения, ФайлОбновленияВерсии, СтрокаЛогов);
ЗапуститьПриложение(КомандаПакетногоОбновления, , Истина, КодВозврата);
Если КодВозврата = 0 Тогда
СообщитьПользователю(НСтр("ru = 'Информационная база успешно обновлена.'"));
ОбновлениеБыло = Истина;
Иначе
СообщитьПользователю(НСтр("ru = 'Ошибка при обновлении информационной базы.'"));
Возврат;
КонецЕсли;
КонецЦикла;
КонецПроцедуры