Извлечение текстов модулей из внешней обработки 1С

Лень в очередной раз сподвигла меня на доработку существующего инструментария.

На этот раз, устав от добавления текстов модулей множества форм в обработке “Анализ процедур и функций”, решил реализовать автоматическую загрузку этих модулей из выгруженных файлов (функционал платформы 1с “Выгрузить в файлы”).

Для внешней обработки формируется следующая структура каталогов.

Текст модуля обработки выгружается в файл “\Ext\ObjectModule.bsl“.

Тексты модулей управляемых форм – в файлы с расширением “.bsl“: “\Forms\НазваниеФормы\Ext\Form\Module.bsl“.

А вот обычные (не управляемые) формы выгружаются в следующие двоичные файлы: “\Forms\НазваниеФормы\Ext\Form.bin“.

Пришлось повозиться с парсингом этих бинарных файлов. Зато опробовал новую (для меня) возможность платформы работы с бинарными файлами

Файл с данными обычной формы представляет из себя бинарный файл с блоками данных.

Блоки разделены секциями, состоящими из 3-х 16-ричных чисел, оканчивающихся числом 7fffffff.

В процессе анализа некоторого количества обработок обнаружилось 2 варианта расположения блоков.

Вариант 1

Вариант 2

Первые 3 блока в моей выборке обработок всегда начинались с одних и тех же адресов :  00000012(hex) или 18(dec), 00000231(hex) или 561(dec), 00000270(hex) или 624(dec)

Я остановился на следующем алгоритме определения необходимой секции, содержащей код модуля формы.

Данный алгоритм был получен империческим путем и не может слепо использоваться в продуктивной разработке!

Если Вы владеете информацией по данному формату, буду рад увидеть Ваш комментарий к данной публикации 🙂

Итак…

Если последнее число 3-го блока = 7fffffff, считаю, что это первый вариант расположения блоков. В остальных случаях – второй вариант.

 

Для первого варианта

Начало блока с текстом модуля формы совпадает с началом 4-го блока (необходимо только пропустить секцию с 3-мя цифрами), т.е. это в 10-чной системе счисления: 691(начало 4-го блока) + 8*3(3 16-чных числа)  + 2(пробелы между числами). Т.е. считаю, что это всегда 717 (dec)

Адрес окончания текстового блока – второе число секции из 3-х чисел + смещение на константу 000002D2(hex) или 722(dec).

Для случая, приведенного на скриншоте (см. выше) получаем:

551(dec) + 722(dec),

где 551(dec) это 00000227(hex)

 

Для второго варианта

Анализируем секцию из 3-х чисел блока 3.

Адрес начала блока с кодом 1С – второе число (к этому числу необходимо еще добавить смещение на константу 722(dec)  и размер секции из 3-х чисел  26(dec)).

Для случая, приведенного на скриншоте (см. выше) получаем:

127773(dec) + 722(dec) + 26(dec),

где 127773(dec) – это 0001F31D(hex)

Адрес окончания блока с кодом 1С – третье число.

Для случая, приведенного на скриншоте (см. выше) получаем:

471603(dec),

где 471603(dec) – это 00073233(hex)

Для чтения из двоичного файла написал процедуру:

Функция ПрочитатьИзФайла(ИмяФайла, Знач Адрес, Знач Размер)	

	МаксимальныйРазмерБуфера = 5000;	

	Результат = "";
	
	Файл = Новый ЧтениеДанных(ИмяФайла);
	Файл.Пропустить(Адрес);			
	Пока Размер > 0 Цикл
		
		ТекущийРазмер = Мин(Размер, МаксимальныйРазмерБуфера);

		РезультатЧтения = Файл.Прочитать(ТекущийРазмер);
		ЧтениеЧасти     = Новый ЧтениеТекста(РезультатЧтения.ОткрытьПотокДляЧтения(), "utf-8");
		
		Результат = Результат + ЧтениеЧасти.Прочитать();
		
		ЧтениеЧасти.Закрыть();
		
		Адрес = Адрес + ТекущийРазмер;
		Размер = Размер - ТекущийРазмер;
		
	КонецЦикла;
	Файл.Закрыть();		
		
	Возврат Результат;
	
КонецФункции // ПрочитатьИзФайла()

 

Ну в заключении, чтобы не “бегать” в конфигуратор для выгрузки обработки в файлы, добавил выгрузку с помощью пакетного запуска конфигуратора 1С с выводом на экран результата выполнения данной выгрузки:

Процедура ДиалогВыбораФайлаСОбработкойДляВыгрузкиСтруктуры(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
	
	Если ВыбранныеФайлы <> Неопределено Тогда 
		
		ВременныйФайл = Новый Файл(ВыбранныеФайлы[0]);
		
		КомандаКонфигуратора = "/DumpExternalDataProcessorOrReportToFiles """ + ДополнительныеПараметры.Диалог.Каталог + ВременныйФайл.ИмяБезРасширения + """ " + """" + ВыбранныеФайлы[0] + """";
		
		ИмяФайлаЛога = ПолучитьИмяВременногоФайла();
		
		ЗапуститьПриложение("""" + КаталогПрограммы() + "1cv8.exe"" DESIGNER /Out""" + ИмяФайлаЛога + """ " + КомандаКонфигуратора,, Истина);
		
		ТекстовыйДокументЛога = Новый ТекстовыйДокумент;
		ТекстовыйДокументЛога.Прочитать(ИмяФайлаЛога);
		ТекстовыйДокументЛога.Показать("Информация о выгрузке обработки в файлы");
		Попытка
			УдалитьФайлы(ИмяФайлаЛога);
		Исключение
		КонецПопытки;		
	КонецЕсли;	
КонецПроцедуры // ДиалогВыбораФайлаСОбработкойДляВыгрузкиСтруктуры()

Ссылка на обработку на infostart и на github

Cсылки к публикации:

Связь процедур и функций в коде

http://v8.1c.ru/o7/201602bin/index.htm

href=”https://github.com/evgenylavelin/analysProcFunc

https://its.1c.ru/db/v8312doc/bookmark/dev/TI000001825

https://wonderland.v8.1c.ru/blog/razvitie-vygruzki-zagruzki-konfiguratsii-v-iz-xml/?sphrase_id=34313

1 комментарий к “Извлечение текстов модулей из внешней обработки 1С”

  1. Святослав

    Добрый день..
    Спасибо.. помогло для начала..)
    Но я немного пошел по другому пути.. искал m o d u l e
    6D 00 6F 00 64 00 75 00 6C 00 65
    109 0 111 0 100 0 117 0 108 0 101

    Затем делитель..
    0D 0A EF BB BF
    13 10 239 187 191

    и затем конец блока кода по 7fffffff и отступал 27 байтов

Оставьте комментарий

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.