Спасибо за ответы. Может кому пригодится, выкладываю написанный на с# проект для чтения метаданных dwg файла без использования autocad. Это почти полный копипаст с темы ссылка из предыдущего поста , просто переписанный на c#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace DwgMetadataRead
{
//Данный материал основан на текстах из форума по дресу http://www.theswamp.org/index.php?topic=36419.msg415688#msg415688
class Program
{
static void Main(string[] args)
{
Dictionary<string, string> dwgFileMetadataInfo = new Dictionary<string, string>();
ReadData(@"D:\temp\test.dwg", dwgFileMetadataInfo);
foreach( string s in dwgFileMetadataInfo.Keys)
Console.WriteLine("{0} --> {1}", s, dwgFileMetadataInfo[s]);
}
static void ReadData(string fileName, Dictionary<string, string> dwgFileMetadataInfo)
{
using (FileStream fs = new FileStream(fileName, FileMode.Open))
{
using (BinaryReader br = new BinaryReader(fs))
{
//Первые 6 байт в файле акада представляют версию в которой был сохранен файл
string acadVersion = new string(br.ReadChars(6));
int acadVersionNUmber;
bool isUnicode = true;
switch (acadVersion)
{
case "AC1027":
acadVersionNUmber = 2013;
break;
case "AC1024":
acadVersionNUmber = 2010;
break;
case "AC1021":
acadVersionNUmber = 2007;
break;
case "AC1018":
acadVersionNUmber = 2004;
isUnicode = false;
break;
//Поддержка формата Autocad 2000 отсутсвует, ибо мне он не нужен, сори.
//case "AC1015":
// acadVersionNUmber = 2000;
// break;
default:
throw new ApplicationException("Файл данной версии AUTOCAD не поддерживается или он создан не в ПО AUTOCAD");
//break;
}
//Console.WriteLine("{0} --> {1}", acadVersion, acadVersionNUmber);
dwgFileMetadataInfo.Add("acad version", acadVersionNUmber.ToString());
//По адресу 0х20 в фале акада находится значение, которое содердит адрес по которому
//начинаются метаданые файла (немного запутанно, но как есть)
fs.Seek(0x20, SeekOrigin.Begin);
//Считаем адрес в переменную
uint si = br.ReadUInt32();
//переместимся по адрусу, который находится в переменной si
fs.Seek(si, SeekOrigin.Begin);
/* Теперь считаем метаданные файла именно в строго определенном порядке:
* title, subject, author, keywords, comments, lastSavedBy, revisionNumber??, hyperlinkBase */
if (isUnicode)
FillDict(dwgFileMetadataInfo, br, ReadUnicode);
else FillDict(dwgFileMetadataInfo, br, ReadASCII);
/* Сразу за полем hyperlinkBase в фале идут данные про время редактирования
* время создания и время последнего изменения
* данные имеют формат: <Юлианская дата (JDN)>.<кол-во милисекунд>
* Каждое значение предстваляет собой 4х байтовое число
* Нам придется сконвертировать юлианскую дату в григорианскую
* JDN даст нам дату, а милисекунды - время */
uint tet1 = br.ReadUInt32();//Время редактирования файла JDN = на всех моих файлах это значение было равно 1
uint tet2 = br.ReadUInt32();//Нас по идее интересуют только милисекунды
uint cdt1 = br.ReadUInt32();//Время создания файла JDN
uint cdt2 = br.ReadUInt32();//Время создания файла милисекунды
uint mdt1 = br.ReadUInt32();//Время последнего изменения файла JDN
uint mdt2 = br.ReadUInt32();//Время последнего изменения файла милисекунды
//Добавим в словарь даты, кроме времени редактирования, мне она не интересна
dwgFileMetadataInfo.Add("creation date", String.Format("{0:yyyy-MM-dd HH:mm}", CalculateDates(cdt1, cdt2)));
dwgFileMetadataInfo.Add("modification date", String.Format("{0:yyyy-MM-dd HH:mm}", CalculateDates(mdt1, mdt2)));
}
}
}
private static string ReadUnicode(BinaryReader br)
{
//Считаем длинну в байтах следующего поля
int len = br.ReadInt16();
if (len > 0)
{
Char[] buffer = new Char[len];
for (int i = 0; i < len; i++)
{
//Так как символ юникода представляется 2мя байтами, то использует функцию ReadInt16
//Сконвертируем полученное число в символ и запишем в массив
buffer[i] = Convert.ToChar(br.ReadInt16());
}
//Соберем из массива символов строку, убрав лишний мусор
return new String(buffer).TrimEnd(Convert.ToChar(0));
}
else
return String.Empty;
}
private static string ReadASCII(BinaryReader br)
{
//Считаем длинну в байтах следующего поля
int len = br.ReadInt16();
if (len > 0)
{
//Прочитаем всю строку целиком и уберем лишний мусор
string s = Encoding.ASCII.GetString(br.ReadBytes(len));
return s.TrimEnd(Convert.ToChar(0));
}
else
return String.Empty;
}
private static DateTime CalculateDates(long jdInt, long jdFrac)
{
/* Функция служит для конвертации юлианской даты в григорианскую
* не желательно использовать для вычисления общего времени редактирования
* Материал взят с сайта http://krutov.org/algorithms/julianday/, также были исправлены опечатки в тексте */
long A, B, C, D, E, monthNumber, yearNumber;// Просто промедуточные коэффициенты
double dayOfMonth;
if (jdInt < 2299161)
{
A = jdInt;
}
else
{
long a = (long)((jdInt - 1867216.25)/36524.25);
A = jdInt + 1 + a - (long)(a/4);
}
B = A + 1524;
C = (long)((B - 122.1)/365.25);
D = (long)(365.25*C);
E = (long)((B - D)/30.6001);
dayOfMonth = Convert.ToDouble(String.Format("{0},{1}", (B - D - (long)(30.6001 * E)), jdFrac));
if ((E == 14) || (E == 15)) monthNumber = E-13;
else if (E < 14) monthNumber = E-1;
else monthNumber = 0;
if (monthNumber > 2) yearNumber = C - 4716;
else if (monthNumber == 2 || monthNumber == 1)
yearNumber = C - 4715;
else yearNumber = 0;
//Console.WriteLine("{0:yyyy-MM-dd HH:mm}", new DateTime(year: (int)yearNumber, month: (int)monthNumber, day: (int)dayOfMonth).AddMilliseconds(jdFrac).ToLocalTime());
return new DateTime(year: (int)yearNumber, month: (int)monthNumber, day: (int)dayOfMonth).AddMilliseconds(jdFrac).ToLocalTime();
}
private static void FillDict(Dictionary<string, string> dict, BinaryReader br, Func<BinaryReader, string> fillFunc)
{
//Поскольку мы имеем 8 полей, то вызываем функцию считывания 8 раз
dict.Add("title", fillFunc(br));
dict.Add("subject", fillFunc(br));
dict.Add("author", fillFunc(br));
dict.Add("keywords", fillFunc(br));
dict.Add("comments", fillFunc(br));
dict.Add("lastSavedBy", fillFunc(br));
dict.Add("revisionNumber", fillFunc(br));
dict.Add("hyperlinkBase", fillFunc(br));
}
}
}
Подскажите пожалуйста, как можно просто загрузить базу данных чертежа без его открытия.