Не претендую на какую-либо уникальность, но надеюсь мой опыт окажется полезным. Для запуска скриптов используется http://oscript.io/.
Автоматическое обновление информационных баз
Процесс обновление информационных баз - достаточно долгое и трудоемкое занятие. Даже если на обслуживании находятся крайне небольшое количество баз - "ручной" порядок обновления, с необходимостью открывать каждую информационную базу, превращается в пытку. Данный скрипт позволяет автоматизировать процесс обновления.
Для работы скрипта необходимо указать логин и пароль для загрузки обновлений, параметры конфигураций и собственно параметры доступа к информационным базам.
На основании скрипта создана библиотека https://github.com/BlackDrak0n/oscript-AutoUpdateIB. На странице проекта доступна исчерпывающая дукументация по процедурам и функциям. Настоятельно рекомендую к скачиванию и подключению к OneScript.
При написание скрипта использовался код из //infostart.ru/public/519499/.
Порядок действий скрипта:
- Получает параметры обновления конфигурации.
- Загружает файл со списком обновлений с сервера проверки обновлений для конфигурации.
- Анализирует полученный файл, собирает сведения о версиях.
- Получает текущую версию и признак изменения конфигурации;
- Ищет в каталоге файлов обновлений версию доступную для обновления;
- Если доступных для обновления версий не найдено - скачивает обновление с сервера обновлений;
- Завершает работу пользователей и устанавливает запрет на подключение новых соединений (только для конфигураций на БСП);
- Создает резервную копию информационной базы;
- Выполняет отложенные обработчики обновления (только для конфигураций на БСП);
- Загружает файл обновления в информационную базу;
- Обновляет конфигурации информационной базы;
- Выполняет тестирование и исправление;
- Принимает обновления в информационной базе (только для конфигураций на БСП);
- Повторяет все с п.4 пока не обновится на последнюю доступную версию;
- В случае ошибки пытается восстановиться из резервной копии (для файловых баз);
- Разрешает подключение новых соединений (только для конфигураций на БСП).
Код скрипта
#Использовать logos
#Использовать v8runner
Перем Лог;
Перем Каталоги;
Перем НастройкиПодключения;
Перем Аутентификация;
Перем ИнтервалыОжидания;
//////////////////////////////////////////////////////////////////////////////////////
// Инициализация
// Инициализация параметров
Функция Инициализировать()
СистемнаяИнформация = Новый СистемнаяИнформация();
КаталогTEMP = СистемнаяИнформация.ПолучитьПеременнуюСреды("TEMP");
КаталогAPPDATA = СистемнаяИнформация.ПолучитьПеременнуюСреды("APPDATA");
Каталоги = Новый Структура();
Каталоги.Вставить("КаталогФайловОбновления", ОбъединитьПути(КаталогAPPDATA, "1C\1Cv8\tmplts\1c")); // Каталог с файлами обновления конфигураций.
Каталоги.Вставить("КаталогВременныхФайлов", ОбъединитьПути(КаталогTEMP, "AutoUpdateIB")); // Каталог для хранения временных файлов.
Каталоги.Вставить("КаталогРезервныхКопий", ОбъединитьПути(КаталогTEMP, "AutoUpdateIB\DumpIB")); // Каталог для хранения резевных копий и файлов дампа.
НастройкиПодключения = Новый Структура();
НастройкиПодключения.Вставить("СерверПроверкиОбновлений", "downloads.1c.ru"); // Адрес сервера для проверки наличия обновлений (открытая часть).
НастройкиПодключения.Вставить("ПутьКФайлуПроверкиОбновлений", "/ipp/ITSREPV/V8Update/Configs"); // Путь к файлу проверки обновлений на сервере.
НастройкиПодключения.Вставить("СерверОбновлений", "downloads.v8.1c.ru"); //Адрес сервера обновлений (закрытая часть).
НастройкиПодключения.Вставить("ПутьКФайлуОбновлений", "/tmplts"); // Путь к файлу обновлений на сервере.
Аутентификация = Новый Структура();
Аутентификация.Вставить("Пользователь", ""); // Имя пользователя для загрузки обновлений.
Аутентификация.Вставить("Пароль", ""); // Пароль пользователя для загрузки обновлений.
ИнтервалыОжидания = Новый Структура();
ИнтервалыОжидания.Вставить("ЗавершениеРаботыПользователей", 900); // Максимальный интервал ожидания завершения сеансов пользователей.
ИнтервалыОжидания.Вставить("ЗавершениеСеансовФайловойИБ", 60); // Максимальный интервал ожидания завершения сеанса файловой информационной базы.
ИнтервалыОжидания.Вставить("ЗавершениеСеансовСервернойИБ", 2); // Интервал ожидания завершения сеанса клиент-серверной информационной базы.
//////////////////////////////////////////////////////////////////////////////////////
// Пример
// Бухгалтерия предприятия, редакция 3.0
ПараметрыОбновленияКонфигурации = ПолучитьПараметрыОбновленияКонфигурации();
Если ПараметрыОбновленияКонфигурации <> Неопределено Тогда
ПараметрыПодключения = ПолучитьПараметрыПодключения(,"\\server\1C base\InfoBase 8.3 (Accounting 3.0)",,,,"Иванов И.И.","Password");
ОбновитьИнформационнуюБазу(ПараметрыОбновленияКонфигурации, ПараметрыПодключения);
ПараметрыПодключения = ПолучитьПараметрыПодключения(,,"Server","Base1C");
ОбновитьИнформационнуюБазу(ПараметрыОбновленияКонфигурации, ПараметрыПодключения);
КонецЕсли;
// Зарплата и управление персоналом, редакция 3.0
ПараметрыОбновленияКонфигурации = ПолучитьПараметрыОбновленияКонфигурации("HRM", "3.0");
Если ПараметрыОбновленияКонфигурации <> Неопределено Тогда
ПараметрыПодключения = ПолучитьПараметрыПодключения(,"\\server\1C base\InfoBase 8.3 (HRM 3.0)",,,,"Иванов И.И.","Password");
ОбновитьИнформационнуюБазу(ПараметрыОбновленияКонфигурации, ПараметрыПодключения);
КонецЕсли;
КонецФункции
///////////////////////////////////////////////////////////////////////////////
// Получение параметров конфигурации
// Загружает файл со списком обновлений с сервера проверки обновлений для конфигурации.
// Анализирует полученный файл, собирает сведения о версиях.
//
// Параметры:
// ТипКонфигурации - Строка - Краткое наименование конфигурации (Accounting - бухгалтерия, HRM - ЗУП ...).
// ВерсияРелиза - Строка - Версия релиза.
// ВерсияПлатформы - Строка - Версия платформы (82, 83).
//
// Возвращаемое значение:
// Структура, Неопределено - Параметры обновления конкретной конфигурации, неопределено в случае ошибки.
//
Функция ПолучитьПараметрыОбновленияКонфигурации(ТипКонфигурации = "Accounting",
ВерсияРелиза = "30",
ВерсияПлатформы = "83")
Лог.Информация("======================================================================");
Лог.Информация(СтрШаблон(НСтр("ru = 'Конфигурация %1, релиз %2, платформа %3.'"),
ТипКонфигурации, ВерсияРелиза, ВерсияПлатформы));
Лог.Информация("======================================================================");
ПараметрыОбновленияКонфигурации = Новый Структура();
ПараметрыОбновленияКонфигурации.Вставить("ТипКонфигурации", ТипКонфигурации);
ПараметрыОбновленияКонфигурации.Вставить("ВерсияРелиза", ВерсияРелиза);
ПараметрыОбновленияКонфигурации.Вставить("ВерсияПлатформы", ВерсияПлатформы);
РезультатВыполнения = ПроверитьКорректностьПараметровОбновленияКонфигурациия(ПараметрыОбновленияКонфигурации);
Если Не РезультатВыполнения Тогда
Возврат Неопределено;
КонецЕсли;
РезультатВыполнения = ПолучитьСпискиОбновленияКонфигурациии(ПараметрыОбновленияКонфигурации);
Если Не РезультатВыполнения Тогда
Возврат Неопределено;
КонецЕсли;
МассивОбновлений = ПроанализироватьСпискиОбновленияКонфигурации(ПараметрыОбновленияКонфигурации);
Если МассивОбновлений = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ПараметрыОбновленияКонфигурации.Вставить("МассивОбновлений", МассивОбновлений);
Возврат ПараметрыОбновленияКонфигурации;
КонецФункции
// Осуществляет проверку корректности заполнения параметров конфигурации
//
// Параметры:
// ПараметрыОбновленияКонфигурации - Структура - Параметры обновления конфигурации (см. в ПолучитьПараметрыОбновленияКонфигурации()).
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения.
//
Функция ПроверитьКорректностьПараметровОбновленияКонфигурациия(ПараметрыОбновленияКонфигурации)
Лог.Информация(НСтр("ru = 'Проверка корректности параметров обновления конфигурации.'"));
Для Каждого ПараметрОбновленияКонфигурации Из ПараметрыОбновленияКонфигурации Цикл
Если ПустаяСтрока(ПараметрОбновленияКонфигурации.Значение) Тогда
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не задан параметр обновления конфигурации: ""%1"".'"), ПараметрОбновленияКонфигурации.Ключ));
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Лог.Отладка(НСтр("ru = 'Проверка корректности параметров обновления конфигурации завершена.'"));
Возврат Истина;
КонецФункции
// Получает файл со списком обновления из Интернета
//
// Параметры:
// ПараметрыОбновленияКонфигурации - Структура - Параметры обновления конфигурации (см. в ПолучитьПараметрыОбновленияКонфигурации()).
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения.
//
Функция ПолучитьСпискиОбновленияКонфигурациии(ПараметрыОбновленияКонфигурации)
Лог.Информация(НСтр("ru = 'Получение списков обновления.'"));
Если НЕ ОбеспечитьКаталог(Каталоги.КаталогВременныхФайлов) Тогда
Возврат Ложь;
КонецЕсли;
ZipФайлСпискаШаблонов = ОбъединитьПути(Каталоги.КаталогВременныхФайлов, "v8upd11.zip");
ФайлСпискаШаблонов = ОбъединитьПути(Каталоги.КаталогВременныхФайлов, "v8cscdsc.xml");
// Получаем сам файл из Интернета.
Попытка
Соединение = Новый HTTPСоединение(НастройкиПодключения.СерверПроверкиОбновлений, , Аутентификация.Пользователь, Аутентификация.Пароль,);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось установить HTTP-соединение с сервером %1:
|%2'"), НастройкиПодключения.СерверПроверкиОбновлений, ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
АдресРесурса = СтрШаблон("%1/%2/%3/%4/v8upd11.zip",
НастройкиПодключения.ПутьКФайлуПроверкиОбновлений, ПараметрыОбновленияКонфигурации.ТипКонфигурации, ПараметрыОбновленияКонфигурации.ВерсияРелиза, ПараметрыОбновленияКонфигурации.ВерсияПлатформы);
Попытка
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса);
Соединение.Получить(HTTPЗапрос, ZipФайлСпискаШаблонов);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось получить файл с сервера %1:
|%2'"), НастройкиПодключения.СерверПроверкиОбновлений, ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
// Распаковываем файл
Попытка
ФайлZip = Новый ЧтениеZipФайла(ZipФайлСпискаШаблонов);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось прочесть архив %1:
|%2'"), ZipФайлСпискаШаблонов, ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
ФайлZip.ИзвлечьВсе(Каталоги.КаталогВременныхФайлов);
ФайлZip.Закрыть();
// Очищаем устаревшие файлы
Попытка
УдалитьФайлы(ZipФайлСпискаШаблонов);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось удалить временный файл %1:
|%2'"), ZipФайлСпискаШаблонов, ИнформацияОбОшибке()));
КонецПопытки;
Лог.Отладка(НСтр("ru = 'Получение списков обновления завершено.'"));
Возврат Истина;
КонецФункции
// Анализирует файл списка обновлений конфигурации
//
// Параметры:
// ПараметрыОбновленияКонфигурации - Структура - Параметры обновления конфигурации (см. в ПолучитьПараметрыОбновленияКонфигурации()).
//
// Возвращаемое значение:
// Массив, Неопределено - Массив с структурой обновлений конфигурации, неопределено в случае неудачи.
//
Функция ПроанализироватьСпискиОбновленияКонфигурации(ПараметрыОбновленияКонфигурации)
Лог.Информация(НСтр("ru = 'Анализ списков обновления.'"));
ФайлСпискаШаблонов = ОбъединитьПути(Каталоги.КаталогВременныхФайлов, "v8cscdsc.xml");
ФайлСпискаШаблоновОбъект = Новый Файл(ФайлСпискаШаблонов);
Если НЕ ФайлСпискаШаблоновОбъект.Существует() Тогда
Лог.Ошибка(НСтр("ru = 'XML файл списка шаблонов не найден в каталоге.'"));
Возврат Неопределено;
КонецЕсли;
МассивОбновлений = Новый Массив;
// Структура страницы:
// <?xml version="1.0" encoding="UTF-8" ?>
// <v8u:updateList xmlns:v8u="http://v8.1c.ru/configuration-updates" version="1.1">
// <v8u:date>... Дата выпуска ...</v8u:date>
// <v8u:update configuration="... Название конфигурации ...">
// <v8u:vendor>... Поставщик ...</v8u:vendor>
// <v8u:file>... Путь к файлу обновления ...</v8u:file>
// <v8u:size>... Размер файла обновления ...</v8u:size>
// <v8u:version>... Версия ...</v8u:version>
// <v8u:target>... Версия для обновления ...</v8u:target>
// <v8u:target>... Версия для обновления ...</v8u:target>
// </v8u:update>
// </v8u:updateList>
Попытка
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ФайлСпискаШаблонов);
ЧтениеXML.ПерейтиКСодержимому();
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ЛокальноеИмя = "update" И ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ПараметрыВерсии = Новый Структура();
ВерсииДляОбновления = Новый Массив;
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ЛокальноеИмя = "update" Тогда
Прервать; // Дошли до конца блока
КонецЕсли;
Если ЧтениеXML.ЛокальноеИмя = "vendor" Тогда
ЧтениеXML.Прочитать();
ПараметрыВерсии.Вставить("Поставщик", ЧтениеXML.Значение);
ИначеЕсли ЧтениеXML.ЛокальноеИмя = "version" Тогда
ЧтениеXML.Прочитать();
ПараметрыВерсии.Вставить("Версия", СтрЗаменить(ЧтениеXML.Значение, ".", "_"));
ИначеЕсли ЧтениеXML.ЛокальноеИмя = "file" Тогда
ЧтениеXML.Прочитать();
ПараметрыВерсии.Вставить("ПутьКФайлуОбновления", ЧтениеXML.Значение);
ИначеЕсли ЧтениеXML.ЛокальноеИмя = "size" Тогда
ЧтениеXML.Прочитать();
ПараметрыВерсии.Вставить("РазмерФайлаОбновления", ЧтениеXML.Значение);
ИначеЕсли ЧтениеXML.ЛокальноеИмя = "target" Тогда
ЧтениеXML.Прочитать();
ВерсииДляОбновления.Добавить(СтрЗаменить(ЧтениеXML.Значение, ".", "_"));
КонецЕсли;
ЧтениеXML.Прочитать(); // в конец элемента
КонецЦикла;
ПараметрыВерсии.Вставить("ВерсииДляОбновления", ВерсииДляОбновления);
МассивОбновлений.Добавить(ПараметрыВерсии);
КонецЕсли;
КонецЦикла;
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Ошибка при чтении файла списка обновлений.
|%1'"), ИнформацияОбОшибке()));
ЧтениеXML.Закрыть();
Возврат Неопределено;
КонецПопытки;
ЧтениеXML.Закрыть();
Попытка
УдалитьФайлы(ФайлСпискаШаблонов);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось удалить временный файл %1:
|%2'"), ФайлСпискаШаблонов, ИнформацияОбОшибке()));
КонецПопытки;
Лог.Отладка(НСтр("ru = 'Анализ списков обновления завершен.'"));
Возврат МассивОбновлений;
КонецФункции
///////////////////////////////////////////////////////////////////////////////
// Обновление инфорационной базы
// Получает параметры подключения к информационной базе.
//
// Параметры:
// ВариантРаботыИнформационнойБазы - Число - Вариант работы информационной базы: 0 - файловый; 1 - клиент-серверный;
// КаталогИнформационнойБазы - Строка - Каталог информационной базы для файлового режима работы;
// ИмяСервера1СПредприятия - Строка - Имя сервера 1С:Предприятия;
// ИмяИнформационнойБазыНаСервере1СПредприятия - Строка - Имя информационной базы на сервере 1С:Предприятия;
// АутентификацияОперационнойСистемы - Булево - Признак аутентификации операционной системы при создании внешнего подключения к информационной базе;
// ИмяПользователя - Строка - Имя пользователя информационной базы;
// ПарольПользователя - Строка - Пароль пользователя информационной базы;
// ВерсияПлатформы - Строка - Версия платформы (82, 83).
//
// Возвращаемое значение:
// Структура, Неопределено - Параметры подключения к информационной базе, неопределено в случае ошибки.
//
Функция ПолучитьПараметрыПодключения(ВариантРаботыИнформационнойБазы = 0,
КаталогИнформационнойБазы = "",
ИмяСервера1СПредприятия = "",
ИмяИнформационнойБазыНаСервере1СПредприятия = "",
АутентификацияОперационнойСистемы = Ложь,
ИмяПользователя = "Администратор",
ПарольПользователя = "",
ВерсияПлатформы = "83")
Лог.Информация("----------------------------------------------------------------------");
Лог.Информация(СтрШаблон(НСтр("ru = 'Информационная база %1.'"),
?(ВариантРаботыИнформационнойБазы = 0, КаталогИнформационнойБазы, ИмяИнформационнойБазыНаСервере1СПредприятия)));
Лог.Информация("----------------------------------------------------------------------");
ПараметрыПодключения = Новый Структура();
ПараметрыПодключения.Вставить("ВариантРаботыИнформационнойБазы", ВариантРаботыИнформационнойБазы);
ПараметрыПодключения.Вставить("КаталогИнформационнойБазы", КаталогИнформационнойБазы);
ПараметрыПодключения.Вставить("ИмяСервера1СПредприятия", ИмяСервера1СПредприятия);
ПараметрыПодключения.Вставить("ИмяИнформационнойБазыНаСервере1СПредприятия", ИмяИнформационнойБазыНаСервере1СПредприятия);
ПараметрыПодключения.Вставить("АутентификацияОперационнойСистемы", АутентификацияОперационнойСистемы);
ПараметрыПодключения.Вставить("ИмяПользователя", ИмяПользователя);
ПараметрыПодключения.Вставить("ПарольПользователя", ПарольПользователя);
ПараметрыПодключения.Вставить("ВерсияПлатформы", ВерсияПлатформы);
РезультатВыполнения = ПроверитьКорректностьПараметровПодключения(ПараметрыПодключения);
Если Не РезультатВыполнения Тогда
Возврат Неопределено;
КонецЕсли;
Возврат ПараметрыПодключения;
КонецФункции
// Обновляет информационную базу.
//
// Параметры:
// ПараметрыОбновленияКонфигурации - Структура - Параметры обновления текущей конфигурации (см. в ПолучитьПараметрыОбновленияКонфигурации()).
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ПолучитьПараметрыПодключения()).
// БлокироватьСоединенияИБ - Булево - Устанавливать блокировку соединений перед обновлением;
// СоздаватьРезервнуюКопию - Булево - Создавать резервную копию;
// ВыполнитьОтложенныеОбработчики - Булево - Выполнить отложенные обработчики обновления;
// ВыполнятьСжатиеТаблицИБ - Булево - Запускать сжатие таблиц информационной базы;
// ВосстанавливатьИнформационнуюБазу - Булево - Использовать восстановление ИБ в случае падения.
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения.
//
Функция ОбновитьИнформационнуюБазу(ПараметрыОбновленияКонфигурации, ПараметрыПодключения,
БлокироватьСоединенияИБ = Истина,
СоздаватьРезервнуюКопию = Истина,
ВыполнитьОтложенныеОбработчики = Истина,
ВыполнятьСжатиеТаблицИБ = Истина,
ВосстанавливатьИнформационнуюБазу = Истина)
ФайлРезервнойКопии = "";
Пока Истина Цикл
ВерсияДляОбновления = ПроверитьНаличиеОбновлений(ПараметрыОбновленияКонфигурации, ПараметрыПодключения);
Если ВерсияДляОбновления = Неопределено Тогда
Возврат Ложь;
ИначеЕсли ВерсияДляОбновления = "ОбновленийНеТребуется" Тогда
Возврат Истина;
КонецЕсли;
Если БлокироватьСоединенияИБ Тогда
РезультатВыполнения = УстановитьБлокировкуСоединений(ПараметрыПодключения);
Если Не РезультатВыполнения Тогда
Прервать;
КонецЕсли;
КонецЕсли;
Если СоздаватьРезервнуюКопию Тогда
РезультатВыполнения = СоздатьРезервнуюКопию(ПараметрыПодключения, ФайлРезервнойКопии);
Если Не РезультатВыполнения Тогда
Прервать;
КонецЕсли;
КонецЕсли;
Если Не ВерсияДляОбновления = "КонфигурацияИзменена" Тогда
Если ВыполнитьОтложенныеОбработчики Тогда
РезультатВыполнения = ВыполнитьОтложенныеОбработчикиОбновления(ПараметрыПодключения);
Если Не РезультатВыполнения Тогда
Прервать;
КонецЕсли;
КонецЕсли;
РезультатВыполнения = ЗагрузитьФайлОбновленияВИнформационнуюБазу(ПараметрыПодключения, ВерсияДляОбновления);
Если Не РезультатВыполнения Тогда
Прервать;
КонецЕсли;
КонецЕсли;
РезультатВыполнения = ВыполнитьОбновлениеКонфигурацииИнформационнойБазы(ПараметрыПодключения);
Если Не РезультатВыполнения Тогда
Прервать;
КонецЕсли;
Если ВыполнятьСжатиеТаблицИБ Тогда
РезультатВыполнения = ВыполнитьТестированиеИИсправление(ПараметрыПодключения);
Если Не РезультатВыполнения Тогда
Прервать;
КонецЕсли;
КонецЕсли;
РезультатВыполнения = ПринятьОбновленияВИнформационнойБазе(ПараметрыПодключения);
Если Не РезультатВыполнения Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если НЕ РезультатВыполнения И СоздаватьРезервнуюКопию
И ВосстанавливатьИнформационнуюБазу Тогда
ВосстановитьИзРезервнойКопии(ПараметрыПодключения, ФайлРезервнойКопии);
КонецЕсли;
Если БлокироватьСоединенияИБ Тогда
РазрешитьПодключение(ПараметрыПодключения);
КонецЕсли;
Возврат РезультатВыполнения;
КонецФункции
// Осуществляет проверку корректности заполнения параметров подключения
//
// Параметры:
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ПолучитьПараметрыПодключения()).
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения.
//
Функция ПроверитьКорректностьПараметровПодключения(ПараметрыПодключения)
Лог.Информация(НСтр("ru = 'Проверка корректности параметров подключения.'"));
ФайловыйВариантРаботы = ПараметрыПодключения.ВариантРаботыИнформационнойБазы = 0;
Если ФайловыйВариантРаботы Тогда
Если ПустаяСтрока(ПараметрыПодключения.КаталогИнформационнойБазы) Тогда
Лог.Ошибка(НСтр("ru = 'Не задано месторасположение каталога информационной базы.'"));
Возврат Ложь;
КонецЕсли;
Иначе
Если ПустаяСтрока(ПараметрыПодключения.ИмяСервера1СПредприятия) Или ПустаяСтрока(ПараметрыПодключения.ИмяИнформационнойБазыНаСервере1СПредприятия) Тогда
Лог.Ошибка(НСтр("ru = 'Не заданы обязательные параметры подключения: ""Имя сервера""; ""Имя информационной базы на сервере"".'"));
Возврат Ложь;
КонецЕсли;
КонецЕсли;
Лог.Отладка(НСтр("ru = 'Проверка корректности параметров подключения завершена.'"));
Возврат Истина;
КонецФункции
// Проверяет наличие обновлений для информационной базы
//
// Параметры:
// ПараметрыОбновленияКонфигурации - Структура - Параметры обновления текущей конфигурации (см. в ОбработкаКонфигурации()).
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ПолучитьПараметрыПодключения());
//
// Возвращаемое значение:
// Структура, Строка, Неопределено - Параметры версии для обновления, "КонфигурацияИзменена", "ОбновленийНеТребуется", неопределено в случае неудачи.
//
Функция ПроверитьНаличиеОбновлений(ПараметрыОбновленияКонфигурации, ПараметрыПодключения)
Лог.Информация(НСтр("ru = 'Проверка наличия обновлений.'"));
// Получение параметров информационной базы
Соединение = УстановитьВнешнееСоединениеСБазой(ПараметрыПодключения);
Если Соединение = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТекущаяВерсия = СтрЗаменить(Соединение.Метаданные.Версия, ".", "_");
Лог.Информация(СтрШаблон(НСтр("ru = 'Текущая версия конфигурации информационной базы: %1.'"), ТекущаяВерсия));
КонфигурацияИзменена = Соединение.КонфигурацияИзменена();
Соединение = Неопределено;
ОжидатьЗавершения(ПараметрыПодключения);
Если КонфигурацияИзменена Тогда
Лог.Информация(НСтр("ru = 'Основная конфигурация отличается от конфигурации базы данных.'"));
Возврат "КонфигурацияИзменена";
КонецЕсли;
// Прверка наличия обновлений
ВерсияДляОбновления = Неопределено;
ЗагруженноеОбновлениеНайдено = Ложь;
МассивОбновлений = ПараметрыОбновленияКонфигурации.МассивОбновлений;
КоличествоОбновлений = МассивОбновлений.Количество();
Для Сч = 1 По КоличествоОбновлений Цикл
ПараметрыВерсии = МассивОбновлений[КоличествоОбновлений - Сч];
МассивВерсийДляОбновления = ПараметрыВерсии.ВерсииДляОбновления.Найти(ТекущаяВерсия);
Если МассивВерсийДляОбновления = Неопределено Тогда
Продолжить;
КонецЕсли;
КаталогФайлаОбновленияВерсии = ОбъединитьПути(Каталоги.КаталогФайловОбновления, ПараметрыОбновленияКонфигурации.ТипКонфигурации, ПараметрыВерсии.Версия);
ФайлОбновленияВерсии = ОбъединитьПути(КаталогФайлаОбновленияВерсии, "1cv8.cfu");
ФайлОбновленияВерсииОбъект = Новый Файл(ФайлОбновленияВерсии);
Если ФайлОбновленияВерсииОбъект.Существует() Тогда
ЗагруженноеОбновлениеНайдено = Истина;
ВерсияДляОбновления = ПараметрыВерсии;
ВерсияДляОбновления.Вставить("Каталог", КаталогФайлаОбновленияВерсии);
Лог.Информация(СтрШаблон(НСтр("ru = 'Загружена и доступна для обновления версия: %1.'"), ПараметрыВерсии.Версия));
Прервать;
КонецЕсли;
Если ВерсияДляОбновления = Неопределено Тогда
ВерсияДляОбновления = ПараметрыВерсии;
ВерсияДляОбновления.Вставить("Каталог", КаталогФайлаОбновленияВерсии);
КонецЕсли;
КонецЦикла;
Если ВерсияДляОбновления = Неопределено Тогда
Лог.Информация(НСтр("ru = 'Установлена последняя версия. Обновление не требуется.'"));
Возврат "ОбновленийНеТребуется";
КонецЕсли;
// Загрузка файлов обновления
Если Не ЗагруженноеОбновлениеНайдено Тогда
Лог.Информация(СтрШаблон(НСтр("ru = 'Доступна для загрузки версия: %1 (Поставщик %2, размер %3).'"),
ВерсияДляОбновления.Версия, ВерсияДляОбновления.Поставщик, ВерсияДляОбновления.РазмерФайлаОбновления));
Если НЕ ПолучитьФайлыОбновлений(ВерсияДляОбновления) Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Возврат ВерсияДляОбновления;
КонецФункции
// Скачивает из Интернета файлы обновлений.
//
// Параметры:
// ВерсияДляОбновления - Структура - Структура с параметрами версии для обновления.
// * Поставщик - Строка - Поставщик;
// * Версия - Строка - Версия;
// * ПутьКФайлуОбновления - Строка - Путь к файлу обновления;
// * РазмерФайлаОбновления - Строка - Размер файла обновления в байтах.
//
// Возвращаемое значение:
// Булево - признак успешного получения.
//
Функция ПолучитьФайлыОбновлений(ВерсияДляОбновления)
Лог.Информация(СтрШаблон(НСтр("ru = 'Получение файлов обновления версии %1.'"), ВерсияДляОбновления.Версия));
Если НЕ ОбеспечитьКаталог(ВерсияДляОбновления.Каталог) Тогда
Возврат Ложь;
КонецЕсли;
Если НЕ ОбеспечитьКаталог(Каталоги.КаталогВременныхФайлов) Тогда
Возврат Ложь;
КонецЕсли;
ZipФайлОбновления = ОбъединитьПути(Каталоги.КаталогВременныхФайлов, "1cv8.zip");
// Получаем сам файл из Интернета.
Попытка
Соединение = Новый HTTPСоединение(НастройкиПодключения.СерверОбновлений, , Аутентификация.Пользователь, Аутентификация.Пароль,);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось установить HTTP-соединение с сервером %1:
|%2'"), НастройкиПодключения.СерверОбновлений, ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
АдресРесурса = СтрШаблон("%1/%2", НастройкиПодключения.ПутьКФайлуОбновлений, ВерсияДляОбновления.ПутьКФайлуОбновления);
Заголовки = Новый Соответствие();
Заголовки.Вставить("User-Agent", "1C+Enterprise/8.3");
Попытка
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
Соединение.Получить(HTTPЗапрос, ZipФайлОбновления);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось получить файл с сервера %1:
|%2'"), НастройкиПодключения.СерверОбновлений, ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
// Распаковываем файл
Попытка
ФайлZip = Новый ЧтениеZipФайла(ZipФайлОбновления);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось прочесть архив %1:
|%2'"), ZipФайлОбновления, ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
ФайлZip.ИзвлечьВсе(ВерсияДляОбновления.Каталог);
ФайлZip.Закрыть();
// Очищаем устаревшие файлы
Попытка
УдалитьФайлы(ZipФайлОбновления);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось удалить временный файл %1:
|%2'"), ZipФайлОбновления, ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
Лог.Отладка(НСтр("ru = 'Файлы обновления успешно получены.'"));
Возврат Истина;
КонецФункции
// Завершает работу пользователей и устанавливает запрет на подключение новых соединений.
//
// Параметры:
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ПолучитьПараметрыПодключения()).
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения.
//
Функция УстановитьБлокировкуСоединений(ПараметрыПодключения)
Лог.Информация(НСтр("ru = 'Завершение работы пользователей и установка запрета на подключение новых соединений.'"));
// Получение параметров информационной базы
Соединение = УстановитьВнешнееСоединениеСБазой(ПараметрыПодключения);
Если Соединение = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Попытка
Соединение.СоединенияИБ.УстановитьБлокировкуСоединений(
НСтр("ru = 'в связи с необходимостью обновления конфигурации.'"), "ПакетноеОбновлениеКонфигурацииИБ");
Интервал = Соединение.СоединенияИБ.ПараметрыБлокировкиСеансов().ИнтервалОжиданияЗавершенияРаботыПользователей * 1000;
ДатаСтарта = Соединение.СоединенияИБ.ПараметрыБлокировкиСеансов().Начало;
Если Интервал > ИнтервалыОжидания.ЗавершениеРаботыПользователей Тогда
Интервал = ИнтервалыОжидания.ЗавершениеРаботыПользователей;
КонецЕсли;
Лог.Отладка(СтрШаблон(НСтр("ru = 'Параметры блокировки сеансов:
| Интервал ожидания завершения работы пользователей - %1 сек
| Дата старта - %2'"), Интервал, ДатаСтарта));
Если Соединение.ЗначениеЗаполнено(ДатаСтарта) Тогда
Пока ТекущаяДата() - Интервал <= ДатаСтарта Цикл
Если НЕ Соединение.СоединенияИБ.УстановленаБлокировкаСоединений()
ИЛИ Соединение.СоединенияИБ.КоличествоСеансовИнформационнойБазы(Ложь) <= 1 Тогда
Прервать;
КонецЕсли;
Приостановить(15 * 1000); // Ждем 15 секунд до следующей проверки.
КонецЦикла;
Лог.Отладка(СтрШаблон(НСтр("ru = 'Задержка: %1 сек'"), ТекущаяДата() - ДатаСтарта));
КонецЕсли;
Если НЕ Соединение.СоединенияИБ.УстановленаБлокировкаСоединений() Тогда
Лог.Ошибка(НСтр("ru = 'Попытка завершения работы пользователей завершилась безуспешно: отменена блокировка ИБ.'"));
Соединение = Неопределено;
ОжидатьЗавершения(ПараметрыПодключения);
Возврат Ложь;
КонецЕсли;
Если Соединение.СоединенияИБ.КоличествоСеансовИнформационнойБазы(Ложь) <= 1 Тогда
Лог.Отладка(НСтр("ru = 'Установка запрета на подключение новых соединений выполнена.
|Все пользователи завершили работу.'"));
Соединение = Неопределено;
ОжидатьЗавершения(ПараметрыПодключения);
Возврат Истина;
КонецЕсли;
Лог.Отладка(НСтр("ru = 'Принудительное прерывание соединений пользователей.'"));
// после начала блокировки сеансы всех пользователей должны быть отключены
// если этого не произошло пробуем принудительно прервать соединение.
ПараметрыАдминистрирования = Соединение.СтандартныеПодсистемыСервер.ПараметрыАдминистрирования();
ПараметрыАдминистрирования.ПарольАдминистратораИнформационнойБазы = ПараметрыПодключения.ПарольПользователя;
ПараметрыАдминистрирования.ПарольАдминистратораКластера = ПараметрыПодключения.ПарольПользователя;
Соединение.СоединенияИБКлиентСервер.УдалитьВсеСеансыКромеТекущего(ПараметрыАдминистрирования);
Если Соединение.СоединенияИБ.КоличествоСеансовИнформационнойБазы(Ложь) > 1 Тогда
Соединение.СоединенияИБ.РазрешитьРаботуПользователей();
Лог.Ошибка(Соединение.СоединенияИБ.СообщениеОНеотключенныхСеансах());
Соединение = Неопределено;
ОжидатьЗавершения(ПараметрыПодключения);
Возврат Ложь;
КонецЕсли;
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Ошибка при установке запрета на подключение новых соединений.
|%1'"), ИнформацияОбОшибке()));
Соединение = Неопределено;
ОжидатьЗавершения(ПараметрыПодключения);
Возврат Истина;
КонецПопытки;
Соединение = Неопределено;
ОжидатьЗавершения(ПараметрыПодключения);
Лог.Отладка(НСтр("ru = 'Установка запрета на подключение новых соединений выполнена.
|Работа всех пользователей прервана.'"));
Возврат Истина;
КонецФункции
// Создает резервную копию информационной базы.
//
// Параметры:
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ПолучитьПараметрыПодключения());
// ФайлРезервнойКопии - Строка - Полный путь к файлу резервной копии
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения.
//
Функция СоздатьРезервнуюКопию(ПараметрыПодключения, ФайлРезервнойКопии = "")
Лог.Информация(НСтр("ru = 'Создание резервной копии информационной базы.'"));
Если НЕ ОбеспечитьКаталог(Каталоги.КаталогРезервныхКопий) Тогда
Возврат Ложь;
КонецЕсли;
ИмяФайла = "Base" + Формат(ТекущаяДата(), "ДФ=ггММддЧЧммсс");
ФайловыйВариантРаботы = ПараметрыПодключения.ВариантРаботыИнформационнойБазы = 0;
Если ФайловыйВариантРаботы Тогда
ФайлНаличияСоединений = Новый Файл(ОбъединитьПути(ПараметрыПодключения.КаталогИнформационнойБазы, "1Cv8tmp.1CD"));
Если ФайлНаличияСоединений.Существует() Тогда
ИмяФайла = ИмяФайла + "-online";
КонецЕсли;
ПолноеИмяФайла = ОбъединитьПути(Каталоги.КаталогРезервныхКопий, ИмяФайла + ".zip");
Лог.Информация(СтрШаблон(НСтр("ru = 'Файл архива %1.'"), ПолноеИмяФайла));
ФайлZip = Новый ЗаписьZipФайла(ПолноеИмяФайла);
ФайлZip.Добавить(ОбъединитьПути(ПараметрыПодключения.КаталогИнформационнойБазы, "1Cv8.1CD"));
Попытка
ФайлZip.Записать();
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Ошибка при записи файла информационной базы в архив.
|%1'"), ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
Иначе
ПолноеИмяФайла = ОбъединитьПути(Каталоги.КаталогРезервныхКопий, ИмяФайла + ".dt");
Лог.Информация(СтрШаблон(НСтр("ru = 'Файл дампа %1.'"), ПолноеИмяФайла));
УправлениеКонфигуратором = УстановитьУправлениеКонфигуратором(ПараметрыПодключения);
ПараметрыЗапуска = УправлениеКонфигуратором.ПолучитьПараметрыЗапуска();
ПараметрыЗапуска.Добавить(СтрШаблон("/DumpIB ""%1""", ПолноеИмяФайла));
Попытка
УправлениеКонфигуратором.ВыполнитьКоманду(ПараметрыЗапуска);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Ошибка при создании файла дампа информационной базы.
|%1'"), УправлениеКонфигуратором.ВыводКоманды()));
Возврат Ложь;
КонецПопытки
КонецЕсли;
ФайлОбъект = Новый Файл(ПолноеИмяФайла);
Если НЕ ФайлОбъект.Существует() Тогда
Лог.Ошибка(НСтр("ru = 'Файл резервной копии не найден в каталоге.'"));
Возврат Ложь;
КонецЕсли;
Лог.Отладка(НСтр("ru = 'Создание резервной копии информационной базы завершено.'"));
ФайлРезервнойКопии = ПолноеИмяФайла;
Возврат Истина;
КонецФункции
// Выполняет все процедуры отложенного обновления информационной базы
//
// Параметры:
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ПолучитьПараметрыПодключения()).
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения.
//
Функция ВыполнитьОтложенныеОбработчикиОбновления(ПараметрыПодключения)
Лог.Информация(НСтр("ru = 'Выполнение отложенных обработчиков обновления.'"));
Соединение = УстановитьВнешнееСоединениеСБазой(ПараметрыПодключения);
Если Соединение = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Попытка
Соединение.ОбновлениеИнформационнойБазыСлужебный.ВыполнитьОтложенноеОбновлениеСейчас();
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Ошибка при выполнении отложенных обработчиков обновления.
|%1'"),ИнформацияОбОшибке()));
Соединение = Неопределено;
ОжидатьЗавершения(ПараметрыПодключения);
Возврат Истина;
КонецПопытки;
Соединение = Неопределено;
ОжидатьЗавершения(ПараметрыПодключения);
Лог.Отладка(НСтр("ru = 'Выполнение отложенных обработчиков обновления завершено.'"));
Возврат Истина;
КонецФункции
// Загружает файл обновления в информационную базу
//
// Параметры:
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ПолучитьПараметрыПодключения());
// ВерсияДляОбновления - Строка - Версия для обновления.
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения.
//
Функция ЗагрузитьФайлОбновленияВИнформационнуюБазу(ПараметрыПодключения, ВерсияДляОбновления)
Лог.Информация(НСтр("ru = 'Загрузка файла обновления в информационную базу.'"));
УправлениеКонфигуратором = УстановитьУправлениеКонфигуратором(ПараметрыПодключения);
Попытка
УправлениеКонфигуратором.ОбновитьКонфигурацию(ВерсияДляОбновления.Каталог, Ложь);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Ошибка при загрузке файла обновления в информационную базу.
|%1'"), УправлениеКонфигуратором.ВыводКоманды()));
Возврат Ложь;
КонецПопытки;
Лог.Отладка(НСтр("ru = 'Загрузка файла обновления в информационную базу завершена.'"));
Возврат Истина;
КонецФункции
// Выполняет обновление конфигурации информационной базы
//
// Параметры:
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ПолучитьПараметрыПодключения()).
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения.
//
Функция ВыполнитьОбновлениеКонфигурацииИнформационнойБазы(ПараметрыПодключения)
Лог.Информация(НСтр("ru = 'Обновление конфигурации информационной базы.'"));
УправлениеКонфигуратором = УстановитьУправлениеКонфигуратором(ПараметрыПодключения);
Попытка
УправлениеКонфигуратором.ОбновитьКонфигурациюБазыДанных();
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Ошибка при обновлении конфигурации информационной базы.
|%1'"), УправлениеКонфигуратором.ВыводКоманды()));
Возврат Ложь;
КонецПопытки;
Лог.Отладка(НСтр("ru = 'Обновление конфигурации информационной базы завершено.'"));
Возврат Истина;
КонецФункции
// Выполняет тестирование и исправление
//
// Параметры:
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ПолучитьПараметрыПодключения()).
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения.
//
Функция ВыполнитьТестированиеИИсправление(ПараметрыПодключения)
Лог.Информация(НСтр("ru = 'Тестирование и исправление информационной базы.'"));
УправлениеКонфигуратором = УстановитьУправлениеКонфигуратором(ПараметрыПодключения);
ПараметрыЗапуска = УправлениеКонфигуратором.ПолучитьПараметрыЗапуска();
ПараметрыЗапуска.Добавить("/IBCheckAndRepair -IBCompression");
Попытка
УправлениеКонфигуратором.ВыполнитьКоманду(ПараметрыЗапуска);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Ошибка при тестировании и исправлении информационной базы.
|%1'"), УправлениеКонфигуратором.ВыводКоманды()));
Возврат Ложь;
КонецПопытки;
Лог.Отладка(НСтр("ru = 'Тестирование и исправление информационной базы завершено.'"));
Возврат Истина;
КонецФункции
// Выполняет неинтерактивное обновление данных информационной базы
//
// Параметры:
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ПолучитьПараметрыПодключения()).
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения.
//
Функция ПринятьОбновленияВИнформационнойБазе(ПараметрыПодключения)
Лог.Информация(НСтр("ru = 'Принятие обновлений в информационной базе.'"));
Соединение = УстановитьВнешнееСоединениеСБазой(ПараметрыПодключения);
Если Соединение = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Попытка
Результат = Соединение.ОбновлениеИнформационнойБазы.ВыполнитьОбновлениеИнформационнойБазы(Ложь);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Ошибка при принятии изменений в информационной базе.
|%1'"), ИнформацияОбОшибке()));
Соединение = Неопределено;
ОжидатьЗавершения(ПараметрыПодключения);
Возврат Истина;
КонецПопытки;
Соединение = Неопределено;
ОжидатьЗавершения(ПараметрыПодключения);
Если Результат = "Успешно" Тогда
Лог.Отладка(НСтр("ru = 'Принятие обновлений в информационной базе завершено.'"));
Возврат Истина;
ИначеЕсли Результат = "НеТребуется" Тогда
Лог.Отладка(НСтр("ru = 'Принятие обновлений в информационной базе не требуется.'"));
Возврат Истина;
Иначе
Лог.Ошибка(НСтр("ru = 'Ошибка установки монопольного режима.'"));
Возврат Ложь;
КонецЕсли;
КонецФункции
// Восстанавливает информационную базу из резервной копии
//
// Параметры:
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ПолучитьПараметрыПодключения());
// ФайлРезервнойКопии - Строка - Полный путь к файлу резервной копии.
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения.
//
Функция ВосстановитьИзРезервнойКопии(ПараметрыПодключения, ФайлРезервнойКопии)
Лог.Информация(НСтр("ru = 'Восстановление информационной базы из резервной копии.'"));
Если ПустаяСтрока(ФайлРезервнойКопии) Тогда
Лог.Ошибка(НСтр("ru = 'Не указан файл резервной копии.'"));
Возврат Ложь;
КонецЕсли;
ФайловыйВариантРаботы = ПараметрыПодключения.ВариантРаботыИнформационнойБазы = 0;
Если Не ФайловыйВариантРаботы Тогда
Лог.Ошибка(НСтр("ru = 'Восстановление клиент-серверных информационных баз не предусмотрено.'"));
Возврат Ложь;
КонецЕсли;
Попытка
ФайлZip = Новый ЧтениеZipФайла(ФайлРезервнойКопии);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось прочесть архив %1:
|%2'"), ФайлРезервнойКопии, ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
ФайлZip.ИзвлечьВсе(ПараметрыПодключения.КаталогИнформационнойБазы);
ФайлZip.Закрыть();
Лог.Отладка(НСтр("ru = 'Восстановление информационной базы из резервной копии завершено.'"));
Возврат Истина;
КонецФункции
// Разрешает подключение новых соединений.
//
// Параметры:
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ПолучитьПараметрыПодключения()).
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения.
//
Функция РазрешитьПодключение(ПараметрыПодключения)
Лог.Информация(НСтр("ru = 'Разрешение подключений новых соединений.'"));
// Получение параметров информационной базы
Соединение = УстановитьВнешнееСоединениеСБазой(ПараметрыПодключения);
Если Соединение = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Попытка
Соединение.СоединенияИБ.РазрешитьРаботуПользователей();
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Ошибка при разрешении подключений новых соединений.
|%1'"), ИнформацияОбОшибке()));
Соединение = Неопределено;
ОжидатьЗавершения(ПараметрыПодключения);
Возврат Истина;
КонецПопытки;
Соединение = Неопределено;
ОжидатьЗавершения(ПараметрыПодключения);
Лог.Отладка(НСтр("ru = 'Разрешение подключений новых соединений завершено.'"));
Возврат Истина;
КонецФункции
//////////////////////////////////////////////////////////////////////////////////////
// Служебные процедуры и функции
// Проверяет наличия каталога и в случае его отсутствия создает новый.
//
// Параметры:
// Каталог - Строка - Путь к каталогу, существование которого нужно проверить.
//
// Возвращаемое значение:
// Булево - признак существования каталога.
//
Функция ОбеспечитьКаталог(Знач Каталог)
Файл = Новый Файл(Каталог);
Если Не Файл.Существует() Тогда
Попытка
СоздатьКаталог(Каталог);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось создать каталог %1.
|%2'"), Каталог, ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
Если Не Файл.Существует() Тогда
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось создать каталог %1.'"), Каталог));
Возврат Ложь;
КонецЕсли
ИначеЕсли Не Файл.ЭтоКаталог() Тогда
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Каталог %1 не является каталогом.'"), Каталог));
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции
// Ожидает завершения подключений к информационной базе.
//
// Параметры:
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ОбновитьИнформационнуюБазу()).
//
Процедура ОжидатьЗавершения(Знач ПараметрыПодключения)
// Несмотря на установку "Соединение = Неопределено;", на медленных компьютерах Com соединения не успевает
// отваливаться до вызова следующей функции. Это приводит к невозможности установить монопольный доступ и ошибке.
// Для обхода ошибки реализована задержка.
ФайловыйВариантРаботы = ПараметрыПодключения.ВариантРаботыИнформационнойБазы = 0;
Если ФайловыйВариантРаботы Тогда
ФайлНаличияСоединений = Новый Файл(ОбъединитьПути(ПараметрыПодключения.КаталогИнформационнойБазы, "1Cv8tmp.1CD"));
Если Не ФайлНаличияСоединений.Существует() Тогда
Возврат;
КонецЕсли;
ДатаСтарта = ТекущаяДата();
Интервал = ИнтервалыОжидания.ЗавершениеСеансовФайловойИБ;
Пока ТекущаяДата() - Интервал <= ДатаСтарта Цикл
Если Не ФайлНаличияСоединений.Существует() Тогда
Прервать;
КонецЕсли;
Приостановить(100); // Ждем 0.1 секунд до следующей проверки.
КонецЦикла;
Иначе
ДатаСтарта = ТекущаяДата();
Интервал = ИнтервалыОжидания.ЗавершениеСеансовСервернойИБ;
Приостановить(1000 * Интервал);
КонецЕсли;
Лог.Отладка(СтрШаблон(НСтр("ru = 'Задержка: %1 сек'"), ТекущаяДата() - ДатаСтарта));
КонецПроцедуры
// Устанавливает внешнее соединение с информационной базой по переданным параметрам подключения и возвращает указатель
// на это соединение.
//
// Параметры:
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ОбновитьИнформационнуюБазу()).
//
// Возвращаемое значение:
// COMОбъект, Неопределено - указатель на COM-объект соединения или Неопределено в случае ошибки;
//
Функция УстановитьВнешнееСоединениеСБазой(Знач ПараметрыПодключения)
ИмяCOMСоединителя = "V" + ПараметрыПодключения.ВерсияПлатформы + ".COMConnector";
Попытка
COMОбъект = Новый COMОбъект(ИмяCOMСоединителя);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось подключится к другой программе:
|%1'"), ИнформацияОбОшибке()));
Возврат Неопределено;
КонецПопытки;
ФайловыйВариантРаботы = ПараметрыПодключения.ВариантРаботыИнформационнойБазы = 0;
// Формирование строки соединения.
ШаблонСтрокиСоединения = "[СтрокаБазы][СтрокаАутентификации];UC=ПакетноеОбновлениеКонфигурацииИБ";
Если ФайловыйВариантРаботы Тогда
СтрокаБазы = "File = ""&КаталогИнформационнойБазы""";
СтрокаБазы = СтрЗаменить(СтрокаБазы, "&КаталогИнформационнойБазы", ПараметрыПодключения.КаталогИнформационнойБазы);
Иначе
СтрокаБазы = "Srvr = ""&ИмяСервера1СПредприятия""; Ref = ""&ИмяИнформационнойБазыНаСервере1СПредприятия""";
СтрокаБазы = СтрЗаменить(СтрокаБазы, "&ИмяСервера1СПредприятия", ПараметрыПодключения.ИмяСервера1СПредприятия);
СтрокаБазы = СтрЗаменить(СтрокаБазы, "&ИмяИнформационнойБазыНаСервере1СПредприятия", ПараметрыПодключения.ИмяИнформационнойБазыНаСервере1СПредприятия);
КонецЕсли;
Если ПараметрыПодключения.АутентификацияОперационнойСистемы Тогда
СтрокаАутентификации = "";
Иначе
Если СтрНайти(ПараметрыПодключения.ИмяПользователя, """") Тогда
ПараметрыПодключения.ИмяПользователя = СтрЗаменить(ПараметрыПодключения.ИмяПользователя, """", """""");
КонецЕсли;
Если СтрНайти(ПараметрыПодключения.ПарольПользователя, """") Тогда
ПараметрыПодключения.ПарольПользователя = СтрЗаменить(ПараметрыПодключения.ПарольПользователя, """", """""");
КонецЕсли;
СтрокаАутентификации = "; Usr = ""&ИмяПользователя""; Pwd = ""&ПарольПользователя""";
СтрокаАутентификации = СтрЗаменить(СтрокаАутентификации, "&ИмяПользователя", ПараметрыПодключения.ИмяПользователя);
СтрокаАутентификации = СтрЗаменить(СтрокаАутентификации, "&ПарольПользователя", ПараметрыПодключения.ПарольПользователя);
КонецЕсли;
СтрокаСоединения = СтрЗаменить(ШаблонСтрокиСоединения, "[СтрокаБазы]", СтрокаБазы);
СтрокаСоединения = СтрЗаменить(СтрокаСоединения, "[СтрокаАутентификации]", СтрокаАутентификации);
Попытка
Соединение = COMОбъект.Connect(СтрокаСоединения);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось подключится к другой программе:
|%1'"), ИнформацияОбОшибке()));
Возврат Неопределено;
КонецПопытки;
Возврат Соединение;
КонецФункции
// Устанавливает контекст библиотеки v8runner и возвращиет указатель на объект.
//
// Параметры:
// ПараметрыПодключения - Структура - Параметры подключения к информационной базе (см. в ОбновитьИнформационнуюБазу()).
//
// Возвращаемое значение:
// УправлениеКонфигуратором - объект библиотеки v8runner;
//
Функция УстановитьУправлениеКонфигуратором(Знач ПараметрыПодключения)
УправлениеКонфигуратором = Новый УправлениеКонфигуратором();
ФайловыйВариантРаботы = ПараметрыПодключения.ВариантРаботыИнформационнойБазы = 0;
Если ФайловыйВариантРаботы Тогда
СтрокаСоединения = "/F""&КаталогИнформационнойБазы""";
СтрокаСоединения = СтрЗаменить(СтрокаСоединения, "&КаталогИнформационнойБазы", ПараметрыПодключения.КаталогИнформационнойБазы);
Иначе
СтрокаСоединения = "/IBConnectionString""Srvr = ""&ИмяСервера1СПредприятия""; Ref = ""&ИмяИнформационнойБазыНаСервере1СПредприятия""""";
СтрокаСоединения = СтрЗаменить(СтрокаСоединения, "&ИмяСервера1СПредприятия", ПараметрыПодключения.ИмяСервера1СПредприятия);
СтрокаСоединения = СтрЗаменить(СтрокаСоединения, "&ИмяИнформационнойБазыНаСервере1СПредприятия", ПараметрыПодключения.ИмяИнформационнойБазыНаСервере1СПредприятия);
КонецЕсли;
Если ПараметрыПодключения.АутентификацияОперационнойСистемы Тогда
ПараметрыПодключения.ИмяПользователя = "";
ПараметрыПодключения.ПарольПользователя = "";
КонецЕсли;
УправлениеКонфигуратором.УстановитьКонтекст(СтрокаСоединения, ПараметрыПодключения.ИмяПользователя, ПараметрыПодключения.ПарольПользователя);
УправлениеКонфигуратором.УстановитьКлючРазрешенияЗапуска("ПакетноеОбновлениеКонфигурацииИБ");
УправлениеКонфигуратором.КаталогСборки(Каталоги.КаталогВременныхФайлов);
Возврат УправлениеКонфигуратором;
КонецФункции
Лог = Логирование.ПолучитьЛог("oscript.app.AutoUpdateIB");
Инициализировать();
Очистка кэша 1С
На практике очень часто встречаются проблемы вызванные переполнением или ошибками в кэше. Решение этих проблем достаточно простое - по новой добавить информационную базу в список или очистить кэш. Однако объяснить клиентам ни то что местонахождение кэша, но и то как открыть скрытую папку иногда крайне проблематично. Данный скрипт полностью решает проблему удаляя ненужный кэш без лишних вопросов и настроек.
Порядок действий скрипта:
- Получает путь к каталогу пользователя;
- Проверяет наличие каталога с кэшем 1С;
- Удаляет кэш с учетом прописанных исключений.
Код скрипта
#Использовать logos
Перем Лог;
Функция Инициализировать()
МассивИсключений = Новый Массив;
МассивИсключений.Добавить("ExtCompT");
КаталогиКэша = Новый Массив;
КаталогиКэша.Добавить("%USERPROFILE%\Local Settings\Application Data\1C\1Cv8");
КаталогиКэша.Добавить("%USERPROFILE%\Application Data\1C\1Cv8");
КаталогиКэша.Добавить("%USERPROFILE%\Local Settings\Application Data\1C\1Cv82");
КаталогиКэша.Добавить("%USERPROFILE%\Application Data\1C\1Cv82");
ОчиститьКэш(КаталогиКэша, МассивИсключений);
КонецФункции
// Перемещаят найденные по маскам файлы в каталог резервных копий.
//
// Параметры:
// КаталогиКэша - Массив - Пути к каталогам кэша для очистки;
// МассивИсключений - Массив - Имена каталогов, пропускаемых при очистке.
//
Процедура ОчиститьКэш(КаталогиКэша, МассивИсключений)
СистемнаяИнформация = Новый СистемнаяИнформация();
ИмяПапкиПользователя = СистемнаяИнформация.ПолучитьПеременнуюСреды("USERPROFILE");
Для Каждого КаталогКэша Из КаталогиКэша Цикл
Путь = СтрЗаменить(КаталогКэша, "%USERPROFILE%", ИмяПапкиПользователя);
Лог.Информация("----------------------------------------------------------------------");
Лог.Информация(СтрШаблон(НСтр("ru = 'Обработка каталога %1.'"), Путь));
Лог.Информация("----------------------------------------------------------------------");
КаталогОбъект = Новый Файл(Путь);
Если НЕ КаталогОбъект.Существует() Тогда
Лог.Ошибка(НСтр("ru = 'Каталог не найден.'"));
Продолжить;
КонецЕсли;
МассивФайлов = НайтиФайлы(Путь, "*", Ложь);
Для Каждого НайденныйФайл Из МассивФайлов Цикл
Если НайденныйФайл.ЭтоКаталог()
И МассивИсключений.Найти(НайденныйФайл.Имя) = Неопределено Тогда
Попытка
УдалитьФайлы(НайденныйФайл.ПолноеИмя);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось удалить каталог %1:
|%2'"), НайденныйФайл.Имя, ИнформацияОбОшибке()));
Продолжить;
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Лог = Логирование.ПолучитьЛог("oscript.app.cleaner");
Инициализировать();
Перенос файлов
Все мы создаем бекапы наших информационных баз. Кто-то делает это ежедневно, кто-то - реже. Естественно мы храним некоторое их количество для возможности отката на определенный момент времени. Каталоги с бекапами под час занимают места в десятки раз больше чем сами информационные базы. А представьте что мы имеем дело с десятком или сотней баз... В попытках уменьшить размер бекапов файловых информационных баз было замечено что в каталоги с базой пользователи часто кидаю посторонние файлы - будь то выгрузки, различные архиви и т.п. Для искоренения подобной практике было принято решение перемещать весь мусор из каталогов с информационными базами в отдельный специально созданный каталог. В скрипте необходимо указать каталоги поиска и каталог для "мусора", отдельно задаются маски для поиска перемещаемых файлов.
Порядок действий скрипта:
- По маске находит файл для переноса;
- Дублирует путь к файлу в каталоге с "мусором";
- Если файл с таким же наименованием уже есть в каталоге - добавляет к имени текущее время;
- Переносит файл.
Код скрипта
#Использовать logos
Перем Лог;
Функция Инициализировать()
РодительскийКаталог = "\\server\---";
КаталогРезервныеКопии = ОбъединитьПути(РодительскийКаталог, "---");
Если НЕ ОбеспечитьКаталог(КаталогРезервныеКопии) Тогда
ВызватьИсключение НСтр("ru = 'Выполнение обработки прервано.'");
КонецЕсли;
КаталогиПоиска = Новый Массив;
КаталогиПоиска.Добавить(ОбъединитьПути(РодительскийКаталог, "---"));
КаталогиПоиска.Добавить(ОбъединитьПути(РодительскийКаталог, "---"));
МассивМасок = Новый Массив;
МассивМасок.Добавить("*.dt");
МассивМасок.Добавить("*.zip");
МассивМасок.Добавить("*.rar");
МассивМасок.Добавить("*.7z");
ПереместитьФайлыВКаталог(КаталогРезервныеКопии, КаталогиПоиска, МассивМасок);
КонецФункции
// Перемещаят найденные по маскам файлы с сохранением пути.
//
// Параметры:
// КаталогРезервныеКопии - Строка - Путь к каталогу в который переносятся файлы;
// КаталогиПоиска - Массив - Пути к каталогам в которых осуществляется поиск файлов;
// МассивМасок - Массив - Маски, по которым осуществляется поиск файлов.
//
Процедура ПереместитьФайлыВКаталог(КаталогРезервныеКопии, КаталогиПоиска, МассивМасок)
Для Каждого КаталогПоиска Из КаталогиПоиска Цикл
Лог.Информация("----------------------------------------------------------------------");
Лог.Информация(СтрШаблон(НСтр("ru = 'Обработка каталога %1.'"), КаталогПоиска));
Лог.Информация("----------------------------------------------------------------------");
КаталогПоискаОбъект = Новый Файл(КаталогПоиска);
Если НЕ КаталогПоискаОбъект.Существует() Тогда
Лог.Ошибка(НСтр("ru = 'Каталог не найден.'"));
Продолжить;
КонецЕсли;
Для Каждого Маска Из МассивМасок Цикл
МассивФайлов = НайтиФайлы(КаталогПоиска, Маска, Истина);
Для Каждого НайденныйФайл Из МассивФайлов Цикл
Лог.Информация(СтрШаблон(НСтр("ru = 'Перемещение файла %1.'"), НайденныйФайл.ПолноеИмя));
НовыйПуть = СтрЗаменить(НайденныйФайл.Путь, КаталогПоиска, КаталогРезервныеКопии);
НовоеИмя = НайденныйФайл.Имя;
Если НЕ ОбеспечитьКаталог(НовыйПуть) Тогда
Продолжить;
КонецЕсли;
ФайлНаДиске = Новый Файл(ОбъединитьПути(НовыйПуть, НовоеИмя));
Если ФайлНаДиске.Существует() Тогда
НовоеИмя = Формат(ТекущаяДата(), "ДФ=ггММддЧЧммсс") + " " + НовоеИмя;
КонецЕсли;
Попытка
ПереместитьФайл(НайденныйФайл.ПолноеИмя, ОбъединитьПути(НовыйПуть, НовоеИмя));
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось переместить файл:
|%1'"), ИнформацияОбОшибке()));
Продолжить;
КонецПопытки;
ФайлНаДиске = Новый Файл(ОбъединитьПути(НовыйПуть, НовоеИмя));
Если НЕ ФайлНаДиске.Существует() Тогда
Лог.Ошибка(НСтр("ru = 'Не удалось корректно переместить файл.'"));
Продолжить;
КонецЕсли;
Лог.Отладка(НСтр("ru = 'Файл перемещен.'"));
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
// Проверяет наличия каталога и в случае его отсутствия создает новый.
//
// Параметры:
// Каталог - Строка - Путь к каталогу, существование которого нужно проверить.
//
// Возвращаемое значение:
// Булево - признак существования каталога.
//
Функция ОбеспечитьКаталог(Знач Каталог)
Файл = Новый Файл(Каталог);
Если Не Файл.Существует() Тогда
Попытка
СоздатьКаталог(Каталог);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось создать каталог %1.
|%2'"), Каталог, ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
ИначеЕсли Не Файл.ЭтоКаталог() Тогда
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Каталог %1 не является каталогом.'"), Каталог));
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции
Лог = Логирование.ПолучитьЛог("oscript.app.copy");
Инициализировать();
От автора
Со временем, если появится интерес к публикации, планирую дополнять список скриптов. Если статья оказалась Вам полезной - пожалуйста, нажмите на "звездочку" и скачайте прилагаемый архив.