Примеры скриптов на OneScript

В своей работе нам часто приходится заниматься рутинными операциями. При небольшом их объеме «ручное» выполнение еще допустимо, но с ростом их числа все мы задумываемся об автоматизации. Вот тут нам на помощь и приходят скрипты. На этом сайте уже выложено немало примеров различных скриптов, вот и я решил внести свою лепту.

Не претендую на какую-либо уникальность, но надеюсь мой опыт окажется полезным. Для запуска скриптов используется http://oscript.io/.

  1. Автоматическое обновление
  2. Очистка кэша
  3. Перенос файлов
  4. От автора

Автоматическое обновление информационных баз

Процесс обновление информационных баз — достаточно долгое и трудоемкое занятие. Даже если на обслуживании находятся крайне небольшое количество баз — «ручной» порядок обновления, с необходимостью открывать каждую информационную базу, превращается в пытку. Данный скрипт позволяет автоматизировать процесс обновления.
Для работы скрипта необходимо указать логин и пароль для загрузки обновлений, параметры конфигураций и собственно параметры доступа к информационным базам.

На основании скрипта создана библиотека https://github.com/BlackDrak0n/oscript-AutoUpdateIB.  На странице проекта доступна исчерпывающая дукументация по процедурам и функциям. Настоятельно рекомендую к скачиванию и подключению к OneScript.

При написание скрипта использовался код из //infostart.ru/public/519499/.

Порядок действий скрипта:

  1. Получает параметры обновления конфигурации.
  2. Загружает файл со списком обновлений с сервера проверки обновлений для конфигурации.
  3. Анализирует полученный файл, собирает сведения о версиях.
  4. Получает текущую версию и признак изменения конфигурации;
  5. Ищет в каталоге файлов обновлений версию доступную для обновления;
  6. Если доступных для обновления версий не найдено — скачивает обновление с сервера обновлений;
  7. Завершает работу пользователей и устанавливает запрет на подключение новых соединений (только для конфигураций на БСП);
  8. Создает резервную копию информационной базы;
  9. Выполняет отложенные обработчики обновления (только для конфигураций на БСП);
  10. Загружает файл обновления в информационную базу;
  11. Обновляет конфигурации информационной базы;
  12. Выполняет тестирование и исправление;
  13. Принимает обновления в информационной базе (только для конфигураций на БСП);
  14. Повторяет все с п.4 пока не обновится на последнюю доступную версию;
  15. В случае ошибки пытается восстановиться из резервной копии (для файловых баз);
  16. Разрешает подключение новых соединений (только для конфигураций на БСП).
Код скрипта
#Использовать logos
#Использовать v8runner

Перем Лог;
Перем Каталоги;
Перем НастройкиПодключения;
Перем Аутентификация;
Перем ИнтервалыОжидания;

//////////////////////////////////////////////////////////////////////////////////////
// Инициализация

// Инициализация параметров
Функция Инициализировать()

СистемнаяИнформация = Новый СистемнаяИнформация();
КаталогTEMP = СистемнаяИнформация.ПолучитьПеременнуюСреды("TEMP");
КаталогAPPDATA = СистемнаяИнформация.ПолучитьПеременнуюСреды("APPDATA");

Каталоги = Новый Структура();
Каталоги.Вставить("КаталогФайловОбновления", ОбъединитьПути(КаталогAPPDATA, "1C1Cv8	mplts1c")); // Каталог с файлами обновления конфигураций.
Каталоги.Вставить("КаталогВременныхФайлов",  ОбъединитьПути(КаталогTEMP, "AutoUpdateIB")); // Каталог для хранения временных файлов.
Каталоги.Вставить("КаталогРезервныхКопий",   ОбъединитьПути(КаталогTEMP, "AutoUpdateIBDumpIB")); // Каталог для хранения резевных копий и файлов дампа.

НастройкиПодключения = Новый Структура();
НастройкиПодключения.Вставить("СерверПроверкиОбновлений",    "downloads.1c.ru"); // Адрес сервера для проверки наличия обновлений (открытая часть).
НастройкиПодключения.Вставить("ПутьКФайлуПроверкиОбновлений", "/ipp/ITSREPV/V8Update/Configs"); // Путь к файлу проверки обновлений на сервере.
НастройкиПодключения.Вставить("СерверОбновлений",      "downloads.v8.1c.ru"); //Адрес сервера обновлений (закрытая часть).
НастройкиПодключения.Вставить("ПутьКФайлуОбновлений",     "/tmplts"); // Путь к файлу обновлений на сервере.

Аутентификация = Новый Структура();
Аутентификация.Вставить("Пользователь", ""); // Имя пользователя для загрузки обновлений.
Аутентификация.Вставить("Пароль",   ""); // Пароль пользователя для загрузки обновлений.

ИнтервалыОжидания = Новый Структура();
ИнтервалыОжидания.Вставить("ЗавершениеРаботыПользователей", 900); // Максимальный интервал ожидания завершения сеансов пользователей.
ИнтервалыОжидания.Вставить("ЗавершениеСеансовФайловойИБ",  60); // Максимальный интервал ожидания завершения сеанса файловой информационной базы.
ИнтервалыОжидания.Вставить("ЗавершениеСеансовСервернойИБ",  2); // Интервал ожидания завершения сеанса клиент-серверной информационной базы.


//////////////////////////////////////////////////////////////////////////////////////
// Пример

// Бухгалтерия предприятия, редакция 3.0
ПараметрыОбновленияКонфигурации = ПолучитьПараметрыОбновленияКонфигурации();
Если ПараметрыОбновленияКонфигурации <> Неопределено Тогда

ПараметрыПодключения = ПолучитьПараметрыПодключения(,"\server1C baseInfoBase 8.3 (Accounting 3.0)",,,,"Иванов И.И.","Password");
ОбновитьИнформационнуюБазу(ПараметрыОбновленияКонфигурации, ПараметрыПодключения);

ПараметрыПодключения = ПолучитьПараметрыПодключения(,,"Server","Base1C");
ОбновитьИнформационнуюБазу(ПараметрыОбновленияКонфигурации, ПараметрыПодключения);

КонецЕсли;

// Зарплата и управление персоналом, редакция 3.0
ПараметрыОбновленияКонфигурации = ПолучитьПараметрыОбновленияКонфигурации("HRM", "3.0");
Если ПараметрыОбновленияКонфигурации <> Неопределено Тогда

ПараметрыПодключения = ПолучитьПараметрыПодключения(,"\server1C baseInfoBase 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. Получает путь к каталогу пользователя;
  2. Проверяет наличие каталога с кэшем 1С;
  3. Удаляет кэш с учетом прописанных исключений.
Код скрипта
#Использовать logos

Перем Лог;

Функция Инициализировать()

МассивИсключений = Новый Массив;
МассивИсключений.Добавить("ExtCompT");

КаталогиКэша = Новый Массив;
КаталогиКэша.Добавить("%USERPROFILE%Local SettingsApplication Data1C1Cv8");
КаталогиКэша.Добавить("%USERPROFILE%Application Data1C1Cv8");
КаталогиКэша.Добавить("%USERPROFILE%Local SettingsApplication Data1C1Cv82");
КаталогиКэша.Добавить("%USERPROFILE%Application Data1C1Cv82");

ОчиститьКэш(КаталогиКэша, МассивИсключений);

КонецФункции

// Перемещаят найденные по маскам файлы в каталог резервных копий.
//
// Параметры:
//  КаталогиКэша   - Массив - Пути к каталогам кэша для очистки;
//  МассивИсключений - Массив - Имена каталогов, пропускаемых при очистке.
//
Процедура ОчиститьКэш(КаталогиКэша, МассивИсключений)

СистемнаяИнформация = Новый СистемнаяИнформация();
ИмяПапкиПользователя = СистемнаяИнформация.ПолучитьПеременнуюСреды("USERPROFILE");

Для Каждого КаталогКэша Из КаталогиКэша Цикл

Путь = СтрЗаменить(КаталогКэша, "%USERPROFILE%", ИмяПапкиПользователя);

Лог.Информация("----------------------------------------------------------------------");
Лог.Информация(СтрШаблон(НСтр("ru = 'Обработка каталога %1.'"), Путь));
Лог.Информация("----------------------------------------------------------------------");

КаталогОбъект = Новый Файл(Путь);
Если НЕ КаталогОбъект.Существует() Тогда
Лог.Ошибка(НСтр("ru = 'Каталог не найден.'"));
Продолжить;
КонецЕсли;

МассивФайлов = НайтиФайлы(Путь, "*", Ложь);
Для Каждого НайденныйФайл Из МассивФайлов Цикл
Если НайденныйФайл.ЭтоКаталог()
И МассивИсключений.Найти(НайденныйФайл.Имя) = Неопределено Тогда
Попытка
УдалитьФайлы(НайденныйФайл.ПолноеИмя);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось удалить каталог %1:
|%2'"), НайденныйФайл.Имя, ИнформацияОбОшибке()));
Продолжить;
КонецПопытки;
КонецЕсли;
КонецЦикла;

КонецЦикла;

КонецПроцедуры

Лог = Логирование.ПолучитьЛог("oscript.app.cleaner");
Инициализировать();

Перенос файлов

Все мы создаем бекапы наших информационных баз. Кто-то делает это ежедневно, кто-то — реже. Естественно мы храним некоторое их количество для возможности отката на определенный момент времени. Каталоги с бекапами под час занимают места в десятки раз больше чем сами информационные базы. А представьте что мы имеем дело с десятком или сотней баз… В попытках уменьшить размер бекапов файловых информационных баз было замечено что в каталоги с базой пользователи часто кидаю посторонние файлы — будь то выгрузки, различные архиви и т.п. Для искоренения подобной практике было принято решение перемещать весь мусор из каталогов с информационными базами в отдельный специально созданный каталог. В скрипте необходимо указать каталоги поиска и каталог для «мусора», отдельно задаются маски для поиска перемещаемых файлов.

Порядок действий скрипта:

  1. По маске находит файл для переноса;
  2. Дублирует путь к файлу в каталоге с «мусором»;
  3. Если файл с таким же наименованием уже есть в каталоге — добавляет к имени текущее время;
  4. Переносит файл.
Код скрипта
#Использовать logos

Перем Лог;

Функция Инициализировать()

РодительскийКаталог = "\server---";

КаталогРезервныеКопии = ОбъединитьПути(РодительскийКаталог, "---");
Если НЕ ОбеспечитьКаталог(КаталогРезервныеКопии) Тогда
ВызватьИсключение НСтр("ru = 'Выполнение обработки прервано.'");
КонецЕсли;

КаталогиПоиска = Новый Массив;
КаталогиПоиска.Добавить(ОбъединитьПути(РодительскийКаталог, "---"));
КаталогиПоиска.Добавить(ОбъединитьПути(РодительскийКаталог, "---"));

МассивМасок = Новый Массив;
МассивМасок.Добавить("*.dt");
МассивМасок.Добавить("*.zip");
МассивМасок.Добавить("*.rar");
МассивМасок.Добавить("*.7z");

ПереместитьФайлыВКаталог(КаталогРезервныеКопии, КаталогиПоиска, МассивМасок);

КонецФункции

// Перемещаят найденные по маскам файлы с сохранением пути.
//
// Параметры:
//  КаталогРезервныеКопии - Строка - Путь к каталогу в который переносятся файлы;
//  КаталогиПоиска     - Массив - Пути к каталогам в которых осуществляется поиск файлов;
//  МассивМасок     - Массив - Маски, по которым осуществляется поиск файлов.
//
Процедура ПереместитьФайлыВКаталог(КаталогРезервныеКопии, КаталогиПоиска, МассивМасок)

Для Каждого КаталогПоиска Из КаталогиПоиска Цикл

Лог.Информация("----------------------------------------------------------------------");
Лог.Информация(СтрШаблон(НСтр("ru = 'Обработка каталога %1.'"), КаталогПоиска));
Лог.Информация("----------------------------------------------------------------------");

КаталогПоискаОбъект = Новый Файл(КаталогПоиска);
Если НЕ КаталогПоискаОбъект.Существует() Тогда
Лог.Ошибка(НСтр("ru = 'Каталог не найден.'"));
Продолжить;
КонецЕсли;

Для Каждого Маска Из МассивМасок Цикл

МассивФайлов = НайтиФайлы(КаталогПоиска, Маска, Истина);
Для Каждого НайденныйФайл Из МассивФайлов Цикл

Лог.Информация(СтрШаблон(НСтр("ru = 'Перемещение файла %1.'"), НайденныйФайл.ПолноеИмя));

НовыйПуть = СтрЗаменить(НайденныйФайл.Путь, КаталогПоиска, КаталогРезервныеКопии);
НовоеИмя = НайденныйФайл.Имя;

Если НЕ ОбеспечитьКаталог(НовыйПуть) Тогда
Продолжить;
КонецЕсли;

ФайлНаДиске = Новый Файл(ОбъединитьПути(НовыйПуть, НовоеИмя));
Если ФайлНаДиске.Существует() Тогда
НовоеИмя = Формат(ТекущаяДата(), "ДФ=ггММддЧЧммсс") + " " + НовоеИмя;
КонецЕсли;

Попытка
ПереместитьФайл(НайденныйФайл.ПолноеИмя, ОбъединитьПути(НовыйПуть, НовоеИмя));
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось переместить файл:
|%1'"), ИнформацияОбОшибке()));
Продолжить;
КонецПопытки;

ФайлНаДиске = Новый Файл(ОбъединитьПути(НовыйПуть, НовоеИмя));
Если НЕ ФайлНаДиске.Существует() Тогда
Лог.Ошибка(НСтр("ru = 'Не удалось корректно переместить файл.'"));
Продолжить;
КонецЕсли;

Лог.Отладка(НСтр("ru = 'Файл перемещен.'"));

КонецЦикла;

КонецЦикла;

КонецЦикла;

КонецПроцедуры

// Проверяет наличия каталога и в случае его отсутствия создает новый.
//
// Параметры:
//  Каталог - Строка - Путь к каталогу, существование которого нужно проверить.
//
// Возвращаемое значение:
//  Булево - признак существования каталога.
//
Функция ОбеспечитьКаталог(Знач Каталог)

Файл = Новый Файл(Каталог);
Если Не Файл.Существует() Тогда
Попытка
СоздатьКаталог(Каталог);
Исключение
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось создать каталог %1.
|%2'"), Каталог, ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
ИначеЕсли Не Файл.ЭтоКаталог() Тогда
Лог.Ошибка(СтрШаблон(НСтр("ru = 'Каталог %1 не является каталогом.'"), Каталог));
Возврат Ложь;
КонецЕсли;

Возврат Истина;

КонецФункции

Лог = Логирование.ПолучитьЛог("oscript.app.copy");
Инициализировать();

От автора

Со временем, если появится интерес к публикации,  планирую дополнять список скриптов. Если статья оказалась Вам полезной — пожалуйста, нажмите на «звездочку» и скачайте прилагаемый архив.

43 Comments

  1. Evil Beaver
    было замечено что в каталоги с базой пользователи часто кидаю посторонние файлы — будь то выгрузки, различные архиви и т.п.

    А можно вопрос — почему они вообще имеют доступ в каталоги бэкапов? А ну как поудаляют их к чертям?

    Reply ↓
  2. artbear

    (0) В исходной ветке тобой указано про текущий код обновления

    Обновление идет на максимально возможный уже скачанный релиз, если такового не найдено — на максимально возможный в пределах скачка (загружается с сайта). Такая необходимость возникла в связи с тем что была куча баз с различными релизами и вместо того чтобы качать цепочку «максимальных» релизов для каждой все релизы обновлялись на уже скачанный и далее по одной цепочке до финального.

    Обработчики в режиме Предприятия не запускаются. Тут принципиальная позиция — соглашение на клиентском компьютере принимает пользователь. Через чур старых ИБ не обновляется — поэтому проблем нет).

    Эта информация верна?

    ИМХО запуск обработок в режиме Предприятия очень важен, миграция данных идет именно в них.

    Reply ↓
  3. artbear

    ИМХО в статье перепутан код скриптов очистки кеша и переноса файлов 🙁

    Reply ↓
  4. ardn

    (1) Evil Beaver,

    Я так понял, что в каталог с базой кидают свои файлы, из-за этого большой размер бекапа получается

    Reply ↓
  5. artbear

    (0) Вместо кода с использованием COM-объекта

    COMОбъект = Новый COMОбъект(«Wscript.Shell»);
    ИмяПапкиПользователя = COMОбъект.ExpandEnvironmentStrings(«%USERPROFILE%»);

    можно юзать встроенный класс

    ПеременныеСреды / EnvironmentVariables()

    Возвращает соответствие переменных среды. Ключом является имя переменной, а значением — значение переменной

    Пример:

    СИ = Новый СистемнаяИнформация();

    Для Каждого Переменная Из СИ.ПеременныеСреды() Цикл

    Сообщить(Переменная.Ключ + » = » + Переменная.Значение);

    КонецЦикла;

    Возвращаемое значение

    Соответствие

    УстановитьПеременнуюСреды / SetEnvironmentVariable()

    Позволяет установить переменную среды. Переменная устанавливается в области видимости процесса и очищается после его завершения.

    Параметры

    varName: Имя переменной

    value: Значение переменной

    ПолучитьПеременнуюСреды / GetEnvironmentVariable()

    Получить значение переменной среды.

    Параметры

    varName: Имя переменной

    Возвращаемое значение

    Строка. Значение переменной

    Показать

    http://oscript.io/syntax/page/%D0%A1%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%BD%D0­%B0%D1%8F%D0%98%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%86%D0­%B8%D1%8F

    Reply ↓
  6. Drak0n

    (1) Evil Beaver, сотрудники имеют доступ только к каталогам с информационными базами. Специфика деятельности такова, что достаточно часто клиенты приносят выгрузки (или архивы с ИБ),которые нужно загрузить или наоборот нужно выгрузить базу клиенту… В общем весь этот мусор сотрудниками копировался и выгружался в папку с ИБ и соответственно с ней же бекапился… От чего размер ежедневных архивов раздувался просто неимоверно).

    (2) artbear, ни коем образом не умоляю важность принятия изменений в режиме Предприятия, однако как уже говорил, у нас принято что бы сам сотрудник, работающий с базой, принимал эти обновления. Но, соглашусь, добавить в код такую возможность надо… Как-нибудь позже…

    (3) artbear, каюсь, исправил (уж очень неудобный редактор текста статьи на инфостарте).

    (5) artbear, спасибо, учту.

    Reply ↓
  7. Drak0n

    Обновил текст скриптов.

    Автоматическое обновление теперь умеет:

    — Выполнять отложенные обработчики обновления (только для конфигураций на БСП);

    — Выполнять тестирование и исправление;

    — Принимать обновления в информационной базе (только для конфигураций на БСП).

    Очистка кэша больше не использует COM объекты.

    Reply ↓
  8. JohnyDeath

    Не хотите положить скрипты в модный github?

    Вот, кстати, еще одна реализация обновлятора баз: https://github.com/ret-Phoenix/autoupdatecfg

    Reply ↓
  9. nixel

    Удивлен, что в скриптах есть работа с конфигуратором, но нет использования библиотеки v8runner 🙂

    Reply ↓
  10. zampollitr

    В скрипте Очистка кэша выдает ошибку:

    {Модуль <string> / Ошибка в строке: 21 / Неизвестный символ: ПолучитьПеременнуюСреды}

    ИмяПапкиПользователя = ПолучитьПеременнуюСреды(«USERPROFILE»);

    Reply ↓
  11. artbear

    (7)

    — Принимать обновления в информационной базе (только для конфигураций на БСП).

    Не совсем понял текст.

    Здесь говорится об обновлении в режиме Предприятие или о чем-то другом ?

    Reply ↓
  12. Drak0n

    (9) nixel, пока только присматриваюсь к возможностям библиотек…

    (10) zampollitr, исправился:

     ИмяПапкиПользователя = СистемнаяИнформация.ПолучитьПеременнуюСреды(«USERPROFILE»);

    (11) artbear, выполняется неинтерактивное обновление данных ИБ.

    Reply ↓
  13. hibico

    Возможен случай, когда конфигурация базы данных отличается от основной конфигурации. А в «Соединение.Метаданные.Версия» возвращается версия конфигурации ИБ.

    В моей конфигурации сначала проверяется «Соединений.КонфигурацияИзменена()» и если изменена, то производится сначала обновление конфигурации ИБ.

    Не понял, а зачем выполняется

    «Соединение.ОбновлениеИнформационнойБазыСлужебный.ВыполнитьОтложенноеОбновлениеСейчас()»

    перед обновлением основной конфигурации?

    Reply ↓
  14. Drak0n

    (13) hibico,

    Соединение.ОбновлениеИнформационнойБазы.ВыполнитьОбновлениеИнформационнойБазы(Ложь);

    В функцию передается параметр отключающий отложенные обработчики обновления (для более быстрого обновления). Соответственно если в информационную базу никто после предыдущего обновления не заходил — эти обработчики будут невыполненными.

    Reply ↓
  15. hibico

    (14)

    Я не про

    Соединение.ОбновлениеИнформационнойБазы.ВыполнитьОбновлениеИнформационнойБазы(Ложь);

    А про строку:

    Соединение.ОбновлениеИнформационнойБазыСлужебный.ВыполнитьОтложенноеОбновлениеСейчас();

    Насколько понимаю, она вызывает запуск отложенных заданий. Если в ней смысл перед обновлением конфигурации?

    Reply ↓
  16. Drak0n

    (15) hibico, риск пропустить какое-нибудь критическое изменение конечно минимален, но, при пакетном обновлении с накатыванием сразу кучи релизов, он присутствует. Да и типовой 1Совский скрипт эту процедуру запускает. Так что лишним не будет.

    Reply ↓
  17. Drak0n

    Новое обновление.

    Автоматическое обновление теперь:

    — Завершает работу пользователей и устанавливает запрет на подключение новых соединений (только для конфигураций на БСП);

    — В случае ошибки пытается восстановиться из резервной копии (для файловых баз);

    — Разрешает подключение новых соединений (только для конфигураций на БСП).

    Теперь корректно отрабатываются ситуации, когда основная конфигурация отличается от конфигурации базы данных.

    Добавлен пример скрипта для работы с файлом списка информационных баз (ibases.v8i).

    Интеграция в скрипты работы с библиотеками logos, v8runner.

    Reply ↓
  18. ret-Phoenix

    (17) Чем не устраивает parserv8i из библиотек к 1script (https://github.com/oscript-library/parserV8i)? там есть и чтение и запись и работа с кешем.

    https://github.com/ret-Phoenix/autoupdatecfg здесь есть функционал по получению последнего релиза, гораздо более простой, скачка файла обновления и запуск конфигуратора с принятием изменений. Запуск в пользовательском режиме при желании можно взять из приведенных Вами скриптов. Опять же там несколько вариантов создания копии баз, прозрачный API.

    https://github.com/ret-Phoenix/scripts здесь на основе выше приведенных реп поиск файловых баз с мертвыми путями и простое архивирование 1cd, вариант с использованием внешнего архиватора.

    Не понимаю, зачем создавать все с нуля, когда есть готовое и можно его улучшить, тем более код там простой, и покрыт тестами.

    Reply ↓
  19. Drak0n

    (18) ret-Phoenix, parserv8i полностью устроил, спасибо за ссылку.

    Reply ↓
  20. hibico

    (17)

      Пока ТекущаяДата() — Интервал <= ДатаСтарта Цикл
    Если Не ФайлНаличияСоединений.Существует() Тогда
    Прервать;
    КонецЕсли;
    КонецЦикла;

    — сюда лучше вставить задержку, например также через «WScript.Shell». А то это ненужная нагрузка на процессор.

    Ну а так осталось, похоже, только отправка сообщения (или лога) по почте.

    Reply ↓
  21. pumbaE

    (20) hibico, в oscript в отличии от 1с есть sleep(1000) = 1 секунда поспать.

    Reply ↓
  22. artbear

    (21) pumbaE, Дополню: в 1скрипт для русского кода реализован Приостановить

    Reply ↓
  23. hibico

    (21) pumbaE,

    Честно сознаюсь, о 1Скрипт узнал только случайно попав на эту публикацию. Был приятно удивлен.

    Сейчас времени нету, но после отпуска обязательно познакомлюсь поближе. Уже есть идеи использования.

    Reply ↓
  24. sorb

    (23) hibico, обязательно поделитесь открытием со своими коллегами, и заходите сюда: https://github.com/EvilBeaver/oscript-library — там уже много идей реализовано 🙂

    Reply ↓
  25. TatiLoz

    (17) Алексей, можете подсказать в чем возможна проблема?

    При загрузке версии релиза возникает ошибка «403 Forbidden». Браузер тоже выдает эту ошибку при попытке загрузки по урл = «http://downloads.v8.1c.ru/get/Info/StateAccounting/1_0_43_5/updsetup.exe».

    Но с n-ой попытки загрузка через браузер срабатывает и после этого начинает работать программная загрузка. Код использую следующий:

    Соединение = Новый HTTPСоединение(«downloads.v8.1c.ru»,,Пользователь,Пароль);
    HTTPЗапрос = Новый HTTPЗапрос(«/get/Info/» + ИмяКонфигурации + «/» + СтрЗаменить(НомерВерсии, «.», «_») + «/updsetup.exe»,Заголовки);
    Ответ = Соединение.Получить(HTTPЗапрос, мФайл.ПолноеИмя);
    Reply ↓
  26. biz-intel

    Пытаюсь выполнить резевное копирование серверной ИБ. Пример скрипта ниже.

    #Использовать AutoUpdateIB
    
    Обновлятор = Новый Обновлятор();
    
    Обновлятор.УстановитьКаталог(«КаталогРезервныхКопий», «D:»);
    
    ПараметрыПодключения = Обновлятор.ПолучитьПараметрыПодключения(1,,»server»,»base»,,»user»,»passwd»,);
    
    Обновлятор.СоздатьРезервнуюКопию(ПараметрыПодключения);
    

    Показать

    Получаю исключение от платформы. На скриншоте видно, что платформа пытается работать с временным файлом по несуществующему пути.

    Reply ↓
  27. JohnyDeath

    (26) Случайно не ConEmu (или cmder) для запуска используете?

    Reply ↓
  28. biz-intel

    (27) нет не использую. Исключение обошёл переопределением переменной temp. Но теперь борюсь с ошибкой «Информационная база не определена». Вообще скрипт нормально работает с файловыми базами, но с серверными лично у меня много проблем, а хочется чтобы скрипты именно с серверными базами помогали

    Reply ↓
  29. JohnyDeath

    (28) Может стоит посмотреть в эту сторону: https://github.com/oscript-library

    в частности сюда: https://github.com/oscript-library/v8runner или сюда: https://github.com/oscript-library/deployka

    Reply ↓
  30. Drak0n

    Это как раз ошибка создания/доступа к файлу лога, создаваемое скриптом библиотеки v8runner (она используется в моей библиотеке для указания параметров запуска конфигуратора). Попробуйте обновить v8runner или свяжитесь с разработчиками. Ссылка выше.

    Reply ↓
  31. biz-intel

    (29) спасибо, но я уже там:) Интересный проект, уверен что это прорыв для нас.

    Reply ↓
  32. biz-intel

    (30) у меня последняя версия стоит, у вас в скрипте есть метод «УстановитьКаталог» с аргументом «КаталогВременныхФайлов». Если переопределить путь лог создается, но дальше возникает не особо обработанное исключение (см. скриншот). Я понимаю что это не в коде скрипта, сейчас как раз смотрю v8runner

    Reply ↓
  33. 4iga-buga

    Помогите пожалуйста, как лог скрипта обновления конфигураций сохранить в файл?

    Reply ↓
  34. 4iga-buga

    (33)разобрался

    Reply ↓
  35. mirco

    Помогите. Почему выдает ошибку

    package-loader.os / Ошибка в строке 184 /неверное значение аргумента

    Библиотека лежит в C:OSlibAutoUpdateIB

    в oscript.cfg

    lib.additional = C:OSlibAutoUpdateIB;

    Reply ↓
  36. Niki_Pro

    (35)

    Проверь корректность наименований в папке «Классы». Аналогичная ошибка была, потому что скачал архив с github, и все русские буквы в наименовании стали крокозябрами. Я их переименовал, но допустил ошибку. Обнаружил ее, и ошибка ушла.

    Reply ↓
  37. dis_2015

    При запуске обновления серверной базы получаю вот такую ошибку (см. скрин). Подскажите как побороть?

    Reply ↓
  38. Drak0n

    В папке со временными файлами есть логи — попробуйте посмотреть там более детальную информацию.

    Скорее всего что-то напутал с кавычками или заменой в функции УстановитьУправлениеКонфигуратором в строке

    СтрокаСоединения = «/IBConnectionString»»Srvr = «»»»&ИмяСервера1СПредприятия»»»»; Ref = «»»»&ИмяИнформационнойБазыНаСервере1СПредприятия»»»»»»»;

    Сейчас негде проверить. Попробуйте заменить на

    СтрокаСоединения = «/IBConnectionString»»Srvr = ‘&ИмяСервера1СПредприятия’; Ref = ‘&ИмяИнформационнойБазыНаСервере1СПредприятия'»»»;
    Reply ↓
  39. dis_2015

    (38)

    Спасибо, помогло!

    Reply ↓
  40. dis_2015

    Серверные базы с Бухгалтерией обновились. А с зарплатой получаю не очень понятную ошибку. Как это побороть?

    ПараметрыОбновленияКонфигурации = ПолучитьПараметрыОбновленияКонфигурации(«HRM», «3.0»);
    Если ПараметрыОбновленияКонфигурации <> Неопределено Тогда
    
    ПараметрыПодключения = ПолучитьПараметрыПодключения(1,,»server1″,»zp3_base»);
    ОбновитьИнформационнуюБазу(ПараметрыОбновленияКонфигурации, ПараметрыПодключения,,Ложь,,Ложь,Ложь);
    
    
    КонецЕсли;

    Показать

    Релиз зупа 3.1. Вставлять «HRM», «3.1» я тоже пробовал. Без результатов.

    Ошибка на скрине

    Reply ↓
  41. Drak0n

    Откройте архив на который ссылается ошибка — там текстовый файл с описанием проблемы. Скорее всего по указанному логину и паролю нет доступа к конфигурации.

    Так же для Базовой, проф и корп версии разные дистрибутивы. Уверены что, например, не HRMBase?

    Reply ↓
  42. dis_2015

    (41) Архив при попытке его извлечь падает с ошибкой. Но при попытке открыть его блокнотом он оказывается html такого содержания:

    <ht ml>
    <head><title>404 Not Found</title></head>
    <body bgcolor=»white»>
    <center><h1>404 Not Found</h1></center>
    <hr><center>nginx/1.12.1</center>
    </body>
    </html>
    

    Показать

    По логину и паролю доступ к обновлениям точно есть. Но зуп у нас корп и я попробовал «HRMCorp» и «HRMCorp30″,»HRM30» результат одинаковый

    Reply ↓
  43. dis_2015

    (42)

    Разобрался правильно в моем случае «HRM», «31»

    Reply ↓

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *