-
-
Save artbear/03fa95cc1c88c861f35d8d611f6153f2 to your computer and use it in GitHub Desktop.
Поиск файловых баз на компьютере https://github.com/EvilBeaver/oscript-library/pull/126#discussion_r70386071
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #Использовать logos | |
| #Использовать tempfiles | |
| Перем Лог; | |
| Перем ЭтоWindows; | |
| Перем Базы; | |
| Перем ОшибкиПоиска; | |
| /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // ОСНОВНЫЕ МЕТОДЫ | |
| // Главная функция. Ищет базы, результат складывает в "bases.csv". Ошибки поиска (например отказы в доступе) складывает в "bases.err" | |
| // Параметры: | |
| // Каталоги - Строка: каталоги поиска, разделенные запятыми | |
| // ИскатьВКаталогах - Булево: если Истина, то осуществляется поиск файлов с расширением ".1CD" | |
| // ИскатьВСпискахБаз - Булево: если Истина, то осуществляется поиск списков баз с расширением ".v8i", в них ищутся файловые базы | |
| // ПолучатьОписаниеБазы - Булево: если Истина, то для каждой базы получается имя и версия конфигуарции | |
| // Исключения - Строка: список слов через запятую, если одно из слов входит в путь, то он пропускается (используется в момент рекурсивного поиска файлов) | |
| Функция НайтиБазы(Знач Каталоги = "", Знач ИскатьВКаталогах = Истина, Знач ИскатьВСпискахБаз = Истина, Знач ПолучатьОписаниеБазы = Истина, Знач Исключения = "") | |
| Лог.Информация("Время начала: " + ТекущаяДата()); | |
| ЭтоWindows = ЭтоWindows(); | |
| // Создадим таблицы для баз, списков баз и исключений | |
| Базы = Новый ТаблицаЗначений; | |
| Базы.Колонки.Добавить("Путь"); | |
| Базы.Колонки.Добавить("Имя"); | |
| Базы.Колонки.Добавить("Конфигурация"); | |
| Базы.Колонки.Добавить("Версия"); | |
| СпискиБаз = Новый ТаблицаЗначений; | |
| СпискиБаз.Колонки.Добавить("Путь"); | |
| СпискиБаз.Колонки.Добавить("Имя"); | |
| СпискиБаз.Колонки.Добавить("Конфигурация"); | |
| СпискиБаз.Колонки.Добавить("Версия"); | |
| ОшибкиПоиска = Новый ТаблицаЗначений; | |
| ОшибкиПоиска.Колонки.Добавить("Путь"); | |
| ОшибкиПоиска.Колонки.Добавить("Описание"); | |
| // Подготовим каталоги поиска: сформируем в виде сыписка | |
| Каталоги = ПривестиСлэшиПодОС(Каталоги); | |
| Каталоги = РазложитьСтрокуВМассивПодстрок(Каталоги, ",", Истина, Истина); | |
| // Подготовим исключения: добавим vrs-cache, сформируем в виде списка | |
| Если СтрЧислоВхождений(Исключения, "vrs-cache") = 0 Тогда | |
| Исключения = Исключения + ",vrs-cache"; | |
| КонецЕсли; | |
| Если СтрЧислоВхождений(Исключения, "1cv8tmp.1cd") = 0 Тогда | |
| Исключения = Исключения + ",1cv8tmp.1cd"; | |
| КонецЕсли; | |
| Исключения = ПривестиСлэшиПодОС(Исключения); | |
| Исключения = РазложитьСтрокуВМассивПодстрок(Исключения, ",", Истина, Истина); | |
| // Поищем базы | |
| Если ИскатьВКаталогах Тогда | |
| Для каждого Каталог Из Каталоги Цикл | |
| НайтиФайлыВКаталоге(Каталог, Базы, ОшибкиПоиска, Исключения, ".1cd"); | |
| КонецЦикла; | |
| КонецЕсли; | |
| Если ИскатьВСпискахБаз Тогда | |
| Для каждого Каталог Из Каталоги Цикл | |
| НайтиФайлыВКаталоге(Каталог, СпискиБаз, ОшибкиПоиска, Исключения, ".v8i"); | |
| КонецЦикла; | |
| НайтиБазыВСпискахБаз(СпискиБаз, Базы); | |
| КонецЕсли; | |
| // Посмотрим, что за базы такие | |
| Если ПолучатьОписаниеБазы Тогда | |
| Для каждого База Из Базы Цикл | |
| Описание = ПолучитьОписаниеБазы(База.Путь); | |
| Если Описание.Получено Тогда | |
| База.Конфигурация = Описание.Конфигурация; | |
| База.Версия = Описание.Версия; | |
| Иначе | |
| Ошибка = ОшибкиПоиска.Добавить(); | |
| Ошибка.Путь = База.Путь; | |
| Ошибка.Описание = Описание.ОписаниеОшибки; | |
| КонецЕсли; | |
| КонецЦикла; | |
| КонецЕсли; | |
| // Свернем и отсортируем таблицы | |
| Базы.Свернуть("Путь, Имя, Конфигурация, Версия"); | |
| Базы.Сортировать("Путь"); | |
| ОшибкиПоиска.Свернуть("Путь", "Описание"); | |
| Базы.Сортировать("Путь"); | |
| // Запишем результаты в файлы | |
| Сообщение = ""; | |
| Если Базы.Количество() > 0 Тогда | |
| Сообщение = "Найдено " + Базы.Количество() + " баз"; | |
| ЗаписатьСписокБаз(Базы); | |
| Иначе | |
| Сообщение = "Базы не найдены"; | |
| КонецЕсли; | |
| Если ОшибкиПоиска.Количество() > 0 Тогда | |
| Сообщение = Сообщение + ", при поиске произошло " + ОшибкиПоиска.Количество() + " ошибок."; | |
| ЗаписатьСписокОшибок(ОшибкиПоиска); | |
| Иначе | |
| Сообщение = Сообщение + ", поиск завершен."; | |
| КонецЕсли; | |
| Лог.Информация(Сообщение); | |
| Лог.ИНформация("Время окончания: " + ТекущаяДата()); | |
| КонецФункции // НайтиБазы | |
| Процедура НайтиФайлыВКаталоге(Знач Путь, Таблица, ОшибкиПоиска, Знач Исключения, Знач Маска) | |
| Попытка | |
| //в отличие от 1С, НайтиФайлы в односкрипте падает при отказе в доступе | |
| Файлы = НайтиФайлы(Путь, "*", Ложь); | |
| Для каждого Файл Из Файлы Цикл | |
| Если ПутьЕстьВИсключениях(Файл.ПолноеИмя, Исключения) Тогда | |
| Продолжить; | |
| ИначеЕсли НРег(Файл.Расширение) = Маска Тогда | |
| стр = Таблица.Добавить(); | |
| Если ЭтоWindows Тогда //компенсация регистронезависимости | |
| стр.Путь = НРег(Файл.ПолноеИмя); | |
| Иначе | |
| стр.Путь = Файл.ПолноеИмя; | |
| КонецЕсли; | |
| Лог.Отладка("Найден файл: " + стр.Путь); | |
| ИначеЕсли Файл.ЭтоКаталог() Тогда | |
| НайтиФайлыВКаталоге(Файл.ПолноеИмя, Таблица, ОшибкиПоиска, Исключения, Маска); | |
| КонецЕсли; | |
| КонецЦикла; | |
| Исключение | |
| //скорее всего банально нет прав | |
| стр = ОшибкиПоиска.Добавить(); | |
| стр.Путь = Путь; | |
| стр.Описание = ОписаниеОшибки(); | |
| Возврат; | |
| КонецПопытки; | |
| КонецПроцедуры // НайтиБазыВКаталоге | |
| Процедура НайтиБазыВСпискахБаз(Знач СпискиБаз, Базы) | |
| Перем Чтение, Строка, Файл; | |
| Для каждого СписокБаз Из СпискиБаз Цикл | |
| Лог.Отладка("Чтение баз из списка: " + СписокБаз.Путь); | |
| Чтение = Новый ЧтениеТекста(СписокБаз.Путь); | |
| Строка = Чтение.ПрочитатьСтроку(); | |
| Пока НЕ Строка = Неопределено Цикл | |
| Если Лев(Строка, 1) = "[" Тогда //начинается описание базы или группы | |
| Имя = СтрЗаменить(Строка, "]", ""); | |
| Имя = СтрЗаменить(Имя, "[", ""); | |
| Строка = Чтение.ПрочитатьСтроку(); | |
| Если НРег(Лев(Строка, 13)) = "connect=file=" Тогда // это файловая база, если "", то серверная, иначе группа | |
| Путь = Сред(Строка, 15); | |
| Путь = СтрЗаменить(Путь, """", ""); | |
| Путь = СтрЗаменить(Путь, ";", "") + "\1Cv8.1CD"; | |
| Путь = ПривестиСлэшиПодОС(Путь); | |
| Файл = Новый Файл(Путь); //если файла нет, то и базы нет | |
| Если Файл.Существует() Тогда | |
| Если ЭтоWindows Тогда //компенсация регистронезависимости | |
| Путь = НРег(Файл.ПолноеИмя); | |
| КонецЕсли; | |
| стр = Базы.Найти(Путь, "Путь"); | |
| Если стр = Неопределено Тогда | |
| стр = Базы.Добавить(); | |
| стр.Путь = Путь; | |
| КонецЕсли; | |
| стр.Имя = Имя; | |
| Лог.Отладка(Символы.Таб + Имя + ": " + Путь); | |
| КонецЕсли; | |
| ИначеЕсли НРег(Лев(Строка, 13)) = "connect=srvr=" Тогда // это серверная база | |
| Лог.Отладка(Символы.Таб + Имя + ": " + Строка + " (пропущено)"); | |
| КонецЕсли; | |
| КонецЕсли; | |
| Строка = Чтение.ПрочитатьСтроку(); | |
| КонецЦикла; | |
| КонецЦикла; | |
| КонецПроцедуры // НайтиБазыВСпискахБаз | |
| Функция ПолучитьОписаниеБазы(Знач Путь) | |
| Перем ФайлОписания, КодВозврата, Описание, Чтение, стр; | |
| Инфо = Новый Структура("Получено, ОписаниеОшибки, Конфигурация, Версия"); | |
| Попытка | |
| ФайлОписания = ВременныеФайлы.НовоеИмяФайла("txt"); | |
| СтрокаЗапуска = "getcfname.exe" + " """ + Путь + """ > " + ФайлОписания; | |
| Если НЕ ЭтоWindows Тогда | |
| СтрокаЗапуска = "wine " + СтрокаЗапуска; | |
| КонецЕсли; | |
| КодВозврата = 0; | |
| Лог.Отладка(СтрокаЗапуска); | |
| //TODO: по какой-то причине файл описания не формируется, хотя из командной строки все отрабабатывает правильно | |
| //ЗапуститьПриложение(СтрокаЗапуска, "", Истина, КодВозврата); | |
| //Обход: | |
| ФайлСкрипта = ОбъединитьПути(ТекущийСценарий().Каталог, "getcfname.cmd"); | |
| Запись = Новый ЗаписьТекста(ФайлСкрипта, "cp866"); | |
| Запись.ЗаписатьСтроку("cd ../bin"); | |
| Запись.ЗаписатьСтроку(СтрокаЗапуска); | |
| Запись.Закрыть(); | |
| ЗапуститьПриложение(ФайлСкрипта, "", Истина, КодВозврата); | |
| Если КодВозврата <> 0 Тогда | |
| ВызватьИсключение "Ошибка запуска приложения: " + СтрокаЗапуска; | |
| КонецЕсли; | |
| Чтение = Новый ЧтениеТекста(ФайлОписания, "cp866"); | |
| Строка = Чтение.Прочитать(); | |
| Чтение.Закрыть(); | |
| Лог.Отладка(Строка); | |
| ПозицияВерсии = Найти(Строка, "("); | |
| Лог.Отладка(ПозицияВерсии); | |
| Если ПозицияВерсии = 0 Тогда | |
| Инфо.Конфигурация = Строка; | |
| Иначе | |
| Инфо.Конфигурация = СокрЛП(Лев(Строка, ПозицияВерсии-1)); | |
| //Инфо.Версия = Сред(Строка, ПозицияВерсии+1, СтрДлина(Строка)-1); - не работает | |
| Инфо.Версия = Сред(Строка, ПозицияВерсии+1); | |
| Инфо.Версия = СтрЗаменить(Инфо.Версия, ")", ""); | |
| КонецЕсли; | |
| Инфо.Получено = Истина; | |
| ВременныеФайлы.УдалитьФайл(ФайлОписания); | |
| Исключение | |
| Инфо.Получено = Ложь; | |
| Инфо.ОписаниеОшибки = ОписаниеОшибки(); | |
| ВременныеФайлы.УдалитьФайл(ФайлОписания); | |
| КонецПопытки; | |
| Возврат Инфо; | |
| КонецФункции // ОписаниПолучитьОписаниеБазы(Путь) | |
| Процедура ЗаписатьСписокБаз(Базы) | |
| Запись = Новый ЗаписьТекста("bases.csv"); | |
| Для каждого База Из Базы Цикл | |
| Запись.ЗаписатьСтроку(База.Путь + "; " + СтрЗаменить(База.Имя, ";", "") + "; " + СтрЗаменить(База.Конфигурация, ";", "") + "; " + База.Версия); | |
| КонецЦикла; | |
| Запись.Закрыть(); | |
| КонецПроцедуры | |
| Процедура ЗаписатьСписокОшибок(Ошибки) | |
| Запись = Новый ЗаписьТекста("bases.err"); | |
| Для каждого Ошибка Из Ошибки Цикл | |
| Запись.ЗаписатьСтроку(Ошибка.Путь + "; " + Ошибка.Описание); | |
| КонецЦикла; | |
| Запись.Закрыть(); | |
| КонецПроцедуры | |
| /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // ВСПОМОГАТЕЛЬНЫЕ МЕТОДЫ | |
| // Взято из БСП | |
| Функция РазложитьСтрокуВМассивПодстрок(Знач Строка, Знач Разделитель = ",", Знач ПропускатьПустыеСтроки = Неопределено, Знач СокращатьНепечатаемыеСимволы = Ложь) | |
| Результат = Новый Массив; | |
| // Для обеспечения обратной совместимости. | |
| Если ПропускатьПустыеСтроки = Неопределено Тогда | |
| ПропускатьПустыеСтроки = ?(Разделитель = " ", Истина, Ложь); | |
| Если ПустаяСтрока(Строка) Тогда | |
| Если Разделитель = " " Тогда | |
| Результат.Добавить(""); | |
| КонецЕсли; | |
| Возврат Результат; | |
| КонецЕсли; | |
| КонецЕсли; | |
| Позиция = СтрНайти(Строка, Разделитель); | |
| Пока Позиция > 0 Цикл | |
| Подстрока = Лев(Строка, Позиция - 1); | |
| Если Не ПропускатьПустыеСтроки Или Не ПустаяСтрока(Подстрока) Тогда | |
| Если СокращатьНепечатаемыеСимволы Тогда | |
| Результат.Добавить(СокрЛП(Подстрока)); | |
| Иначе | |
| Результат.Добавить(Подстрока); | |
| КонецЕсли; | |
| КонецЕсли; | |
| Строка = Сред(Строка, Позиция + СтрДлина(Разделитель)); | |
| Позиция = СтрНайти(Строка, Разделитель); | |
| КонецЦикла; | |
| Если Не ПропускатьПустыеСтроки Или Не ПустаяСтрока(Строка) Тогда | |
| Если СокращатьНепечатаемыеСимволы Тогда | |
| Результат.Добавить(СокрЛП(Строка)); | |
| Иначе | |
| Результат.Добавить(Строка); | |
| КонецЕсли; | |
| КонецЕсли; | |
| Возврат Результат; | |
| КонецФункции // РазложитьСтрокуВМассивПодстрок | |
| Функция ПутьЕстьВИсключениях(Знач Путь, Знач Исключения) | |
| Для каждого Маска Из Исключения Цикл | |
| Если СтрЧислоВхождений(НРег(Путь), НРег(Маска)) > 0 Тогда | |
| Возврат Истина; | |
| КонецЕсли; | |
| КонецЦикла; | |
| Возврат Ложь; | |
| КонецФункции // ПутьЕстьВИсключениях | |
| Функция ЭтоWindows() | |
| СИ = Новый СистемнаяИнформация; | |
| Возврат Найти(СИ.ВерсияОС, "Windows") > 0; | |
| КонецФункции // ЭтоWindows | |
| Функция ПривестиСлэшиПодОС(Знач Путь) | |
| Если ЭтоWindows Тогда | |
| Возврат СтрЗаменить(Путь, "/", "\"); | |
| Иначе | |
| Возврат СтрЗаменить(Путь, "\", "/"); | |
| КонецЕсли; | |
| КонецФункции // ПривестиСлэшиПодОС | |
| /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| Лог = Логирование.ПолучитьЛог("ibmgmt.find-ib"); | |
| Лог.УстановитьУровень(УровниЛога.Отладка); | |
| НайтиБазы("c:\"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment