1C:Enterprise構成フォーマットを操作するためのC#ソースコードを公開することにしました。
https://github.com/elisy/MdInternals
MdInternalsはcf、cfu、epf、erfの形式を理解し、その内容を人間が読めるXmlおよびテキストファイルに解凍し、ダウンロードし直します。 オブジェクトの内部ファイルとプロパティにプログラムでアクセスできます。
プロジェクトは次の部分で構成されています。
- MdInternalsはプログラムでオブジェクトと構成プロパティにアクセスします
- CfProjectは、MdInternalsオブジェクトのシリアル化と逆シリアル化を担当します
- MdInternals.Cilはバイトコード(OpCode)1Cを逆コンパイルします
- MdInternals.Serializationは、フォーム "{19 {" "、2}}"の内部セミJSON形式1Cで動作します
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);
認識されたファイルは、オブジェクトの種類ごとにディレクトリツリーに書き込まれます。 認識されないものは、未解決ディレクトリに配置されます。
認識されたファイルは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 0x7F)、4バイトのページサイズ、8バイトの予約バイトで構成されます。 ファイルのヘッダーがデータページの順序になった後。 前の各ページは次へリンクしています。
各ページ(ImagePage)は、ページタイトル(ImagePageHeader)、ImageRowPointersへのポインターのグループ、およびImageRows領域で構成されます。
ImagePageHeaderページヘッダーには、予約済み2バイト0x0D 0x0A、27バイトのテキスト情報、および予約済み2バイト0x0D 0x0Aが含まれます。 テキスト情報には、すべてのページの合計データサイズ(FullSize)、現在のページのサイズ(PageSize)、ファイル内の次のページのアドレス(NextPageAddress)の3つの16進数が含まれます。 FullSizeは、ページチェーンの最初のページにのみ設定されます。 チェーンの残りのページの場合、この値は0です。チェーンの最後のページの場合、NextPageAddressは0xFF 0xFF 0xFF 0x7Fに設定されます。
ImageRowPointersポインターブロックは、ページのPageSize値で指定されたサイズです。 各ポインターは、4バイトのHeaderAddressヘッダーアドレスと4バイトのBodyAddress本体アドレスで構成されます。 各ポインターの末尾には、署名0xFF 0xFF 0xFF 0x7Fがあります。 アドレスは、ImageRows領域の現在のページ内の場所を示します。
ImageRowHeaderヘッダーは、ImagePageHeaderページタイトルブロックで始まり、ヘッダーに割り当てられているバイト数を報告します。 次に、20個の予約バイト、UTF-16データ識別子(Id)行、および4個の予約バイトがあります。
ImageRowBody本体は、ImagePageHeaderページヘッダーブロックで始まります。これは、データ本体に割り当てられたバイト数を報告します。 データ本文が0xEF 0xBB 0xBF(署名UTF8)で始まる場合、本文にはUTF-8文字列が含まれます。 それ以外の場合、データ本体にはパックデータが含まれます。 展開されたデータが0xFF 0xFF 0xFF 0x7Fで始まる場合、コンテンツはオブジェクトのシーケンスであり、CF形式で書き込まれます。 それ以外の場合、コンテンツはシリアル化文字列です。
実装されていないもの
- ユーティリティは、第1レベルの構成オブジェクトのみを認識し、サブディレクトリに配置します。 残りを認識しません:フォーム、レイアウト、未解決ディレクトリに配置
- 拡張子がimgの複合オブジェクトは、未解決ディレクトリでは解凍されません
- MdInternalsは、限られた数のオブジェクトプロパティを認識します