Работа с форматом конфигураций 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:
Распознанные файлы выгружаются в XML-формате. Формат XML позволяет контролировать логическую целостность файлов и обрабатывать файлы сторонними программами. Известные свойства перемещаются в соответствующие разделы (атрибуты или тэги) XML-структуры:
Чтение из 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 зарезервированных байт. После заголовка файла идут по порядку страницы с данными. Каждая предыдущая страница ссылается на последующую.
Каждая страница (ImagePage) состоит из заголовка страницы (ImagePageHeader), группы указателей на записи ImageRowPointers и области ImageRows.
Заголовок страницы 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 распознает ограниченное числа свойств объектов