Decidí publicar el código fuente de C # para trabajar con el formato de configuración 1C: Enterprise.
https://github.com/elisy/MdInternals
MdInternals entiende el formato cf, cfu, epf, erf, descomprime el contenido en archivos de texto y Xml legibles por humanos, y los vuelve a descargar. Le permite acceder mediante programación a archivos internos y propiedades de objetos.
El proyecto consta de partes:
- MdInternals accede programáticamente a objetos y propiedades de configuración
- CfProject es responsable de serializar y deserializar objetos MdInternals
- MdInternals.Cil descompila bytecode (OpCode) 1C
- MdInternals.Serialization funciona con formato semi-JSON interno 1C de la forma "{19 {" ", 2}}"
Descargar archivos cf, cfu, epf, erf al disco
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);
Los archivos reconocidos se escriben en el árbol de directorios por tipo de objeto. Los no reconocidos se colocan en el directorio No resuelto:

Los archivos reconocidos se cargan en formato XML. El formato XML le permite controlar la integridad lógica de los archivos y procesar archivos con programas de terceros. Las propiedades conocidas se mueven a las secciones apropiadas (atributos o etiquetas) de la estructura XML:

Leer desde una tabla MSSQL
var image = ImageReader.ReadImageFromConfig(@"data source=192.168.1.2\SQL2005;user=login;pwd=password;database=Database1C");
Acceso a archivos internos
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();
Crear un archivo desde el formato xml descargado
var project = new CfProject(); var mp = project.Load(@"D:\Config\Xml\Config.cfproj"); mp.Save(@"D:\config.cf");
Descripción del formato CF
Un archivo cf consta de un encabezado de imagen (ImageHeader) y las páginas que lo siguen (ImagePage1-ImagePageN). El encabezado de la imagen consta de 4 bytes de la firma, que es igual a 0xFF 0xFF 0xFF 0x7F, 4 bytes de tamaño de página y 8 bytes reservados. Después del encabezado del archivo están las páginas de datos en orden. Cada página anterior enlaza con la siguiente.

Cada página (ImagePage) consta de un título de página (ImagePageHeader), un grupo de punteros a ImageRowPointers y un área de ImageRows.

El encabezado de la página ImagePageHeader contiene: 2 bytes reservados 0x0D 0x0A, 27 bytes de información textual y 2 bytes reservados 0x0D 0x0A. La información de texto contiene 3 números hexadecimales: el tamaño total de datos de todas las páginas (Tamaño completo), el tamaño de la página actual (Tamaño de página) y la dirección de la página siguiente en el archivo (Dirección de página siguiente). FullSize se establece solo para la primera página de la cadena de páginas. Para las páginas restantes de la cadena, este valor es 0. Para la última página de la cadena, NextPageAddress se establece en 0xFF 0xFF 0xFF 0x7F.
El bloque de puntero ImageRowPointers es el tamaño especificado en el valor PageSize de la página. Cada puntero consta de 4 bytes de la dirección del encabezado HeaderAddress y 4 bytes de la dirección del cuerpo BodyAddress. Al final de cada puntero está la firma 0xFF 0xFF 0xFF 0x7F. Las direcciones indican ubicaciones dentro de la página actual en el área de ImageRows.
El encabezado ImageRowHeader comienza con el bloque de encabezado de página ImagePageHeader, que informa cuántos bytes se asignan para el encabezado. Los siguientes son 20 bytes reservados, la cadena del identificador de datos (Id) UTF-16 y 4 bytes reservados.
El cuerpo de ImageRowBody comienza con el bloque de encabezado de página ImagePageHeader, que informa cuántos bytes se asignan para el cuerpo de datos. Si el cuerpo de datos comienza en 0xEF 0xBB 0xBF (firma UTF8), entonces el cuerpo contiene una cadena UTF-8. De lo contrario, el cuerpo de datos contiene datos empaquetados. Si los datos desempaquetados comienzan en 0xFF 0xFF 0xFF 0x7F, entonces el contenido es una secuencia de objetos y están escritos en formato CF. De lo contrario, el contenido es una cadena de serialización.
Lo que no está implementado
- La utilidad reconoce solo los objetos de configuración del primer nivel, colocándolos en subdirectorios. No reconoce el resto: formularios, diseños, colocación en el directorio no resuelto
- Los objetos compuestos con la extensión img no se descomprimen en el directorio No resuelto
- MdInternals reconoce un número limitado de propiedades de objeto