Работа с форматом конфигураций 1С: Предприятие

Решил опубликовать исходный код C# для работы с форматом конфигураций 1С: Предприятие.

https://github.com/elisy/MdInternals

MdInternals понимает формат cf, cfu, epf, erf, распаковывает содержимое в удобочитаемые Xml и текстовые файлы и загружает обратно. Позволяет программно обращаться к внутренним файлам и свойствам объектов.

Проект состоит из частей:

  • MdInternals программно обращается к объектам и свойствам конфигурации
  • CfProject отвечает за сериализацию и десериализацию объектов MdInternals
  • MdInternals.Cil декомпилирует байт-код (OpCode) 1С
  • MdInternals.Serialization работает с внутренним полу-JSON форматом 1С вида »{ 19 { », 2 } }»

Выгрузка файлов cf, cfu, epf, erf на диск

var cf = new CfPackage();
//или var cf = new EpfPackage();
//или var cf = new ErfPackage();
//или var cf = new CfuPackage();
cf.Open(@"D:\config.cf");
var project = new CfProject();
project.Save(epf, @"D:\Config\Xml\Config.cfproj", ProjectType.Xml);

Распознанные файлы записываются в дерево каталогов по видам объектов. Нераспознанные помещаются в каталог Unresolved:


image.axd?picture=2019%2f1%2fimage2.png

Распознанные файлы выгружаются в XML-формате. Формат XML позволяет контролировать логическую целостность файлов и обрабатывать файлы сторонними программами. Известные свойства перемещаются в соответствующие разделы (атрибуты или тэги) XML-структуры:

image.axd?picture=2019%2f1%2fimage3.png

Чтение из MSSQL-таблицы

var image = ImageReader.ReadImageFromConfig(@"data source=192.168.1.2\SQL2005;user=login;pwd=password;database=Database1C");

Обращение к внутренним файлам

var mp = new EpfPackage();
mp.Open(file);
var root = mp.MetadataObjects.Where(m => m.ImageRow.FileName == "root").FirstOrDefault();
var rp = new RootPointer(root.ImageRow);
var part = mp.MetadataObjects.Where(m => m.ImageRow.FileName == rp.MetadataPackageFileName.ToString()).FirstOrDefault();


Создание файла из выгруженного xml-формата

var project = new CfProject();
var mp = project.Load(@"D:\Config\Xml\Config.cfproj");
mp.Save(@"D:\config.cf");


Описание Cf-Формата

Cf-файл состоит из заголовка образа (ImageHeader) и следующими за ним страницами (ImagePage1-ImagePageN). Заголовок образа состоит из 4х байт сигнатуры, которая равна 0xFF 0xFF 0xFF 0×7F, 4х байт размера страницы и 8 зарезервированных байт. После заголовка файла идут по порядку страницы с данными. Каждая предыдущая страница ссылается на последующую.

image.axd?picture=2019%2f1%2fimage4.png

Каждая страница (ImagePage) состоит из заголовка страницы (ImagePageHeader), группы указателей на записи ImageRowPointers и области ImageRows.

image.axd?picture=2019%2f1%2fimage1.png

Заголовок страницы ImagePageHeader содержит в себе: зарезервированные 2 байта 0×0D 0×0A, 27 байт текстовой информации и еще зарезервированные 2 байта 0×0D 0×0A. Текстовая информация содержит 3 шестнадцатеричных числа: общий размер данных всех страниц (FullSize), размер текущей страницы (PageSize) и адрес следующей страницы в файле (NextPageAddress). FullSize проставляется только для первой страницы цепочки страниц. Для остальных страниц цепочки это значение 0. Для последней страницы цепочки NextPageAddress принимается равным 0xFF 0xFF 0xFF 0×7F.

Блок указателей ImageRowPointers занимает размер, указанный в значении PageSize страницы. Каждый указатель состоит из 4х байт адреса заголовка HeaderAddress и 4х байт адреса тела BodyAddress. В конце каждого указателя помещается сигнатура 0xFF 0xFF 0xFF 0×7F. Адреса указывают на расположения внутри текущей страницы на область ImageRows.

Заголовок ImageRowHeader начинается с блока заголовка страницы ImagePageHeader, который сообщает, сколько байт отведено под заголовок. Далее идут 20 зарезервированных байт, UTF-16 строка идентификатора данных (Id) и 4 зарезервированных байт.

Тело ImageRowBody начинается с блока заголовка страницы ImagePageHeader, который сообщает, сколько байт отведено под тело данных. Если тело данных начинается на 0xEF 0xBB 0xBF (сигнатура UTF8), то тело содержит UTF-8 строку. Иначе тело данных содержит упакованные данные. Если распакованные данные начинаются на 0xFF 0xFF 0xFF 0×7F, то содержимое — последовательность объектов, и они записаны в CF-формате. Иначе содержимое — это строка сериализации.

Что не реализовано


  • Утилита распознает только объекты конфигурации 1 го уровня, помещая по подкаталогам. Не распознает остальное: формы, макеты, помещая в каталог Unresolved
  • В каталоге Unresolved не распаковываются составные объекты с расширением img
  • MdInternals распознает ограниченное числа свойств объектов

© Habrahabr.ru