using System;
using System.IO;
using System.IO.Packaging;
using System.Reflection;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
private const string pathToRevitFile =
@"pathToRevitFile";
private const string StreamName = "BasicFileInfo";
static void Main(string[] args)
{
if (!StructuredStorageUtils.IsFileStucturedStorage(pathToRevitFile))
throw new NotSupportedException("File is not a structured storage file");
var rawData = GetRawBasicFileInfo(pathToRevitFile);
BasicFileInfo basicFileInfo = new BasicFileInfo();
using (var ms = new MemoryStream(rawData))
{
using (var br = new BinaryReader(ms, System.Text.Encoding.Unicode))
{
basicFileInfo.A = br.ReadInt32();
basicFileInfo.B = br.ReadInt32();
basicFileInfo.C = br.ReadInt16();
var sLen = br.ReadInt32();
basicFileInfo.Path1
= System.Text.Encoding.Unicode.GetString(br.ReadBytes(sLen * 2));
sLen = br.ReadInt32();
basicFileInfo.Version = System.Text.Encoding.Unicode.GetString(br.ReadBytes(sLen * 2));
sLen = br.ReadInt32();
basicFileInfo.Path2 = System.Text.Encoding.Unicode.GetString(br.ReadBytes(sLen * 2));
basicFileInfo.Unknown = br.ReadBytes(5);
sLen = br.ReadInt32();
basicFileInfo.UID = System.Text.Encoding.Unicode.GetString(br.ReadBytes(sLen * 2));
sLen = br.ReadInt32();
basicFileInfo.Localization = System.Text.Encoding.Unicode.GetString(br.ReadBytes(sLen * 2));
//read to end
br.ReadBytes(2); // \r \n
sLen = (int) (br.BaseStream.Length - br.BaseStream.Position) - 2;
var buffer =
br.ReadBytes(sLen);
basicFileInfo.Data = Encoding.Unicode.GetString(buffer);
br.ReadBytes(2); // \r \n
}
}
var rawString = System.Text.Encoding.Unicode.GetString(rawData);
var fileInfoData = rawString.Split(new string[] { "\0", "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
foreach (var info in fileInfoData)
{
Console.WriteLine(info);
}
}
private static byte[] GetRawBasicFileInfo(string revitFileName)
{
if (!StructuredStorageUtils.IsFileStucturedStorage(revitFileName))
throw new NotSupportedException("File is not a structured storage file");
using (StructuredStorageRoot ssRoot =
new StructuredStorageRoot(pathToRevitFile))
{
if (!ssRoot.BaseRoot.StreamExists(StreamName))
throw new NotSupportedException(string.Format("File doesn't contain {0} stream", StreamName));
StreamInfo imageStreamInfo =
ssRoot.BaseRoot.GetStreamInfo(StreamName);
using (Stream stream = imageStreamInfo.GetStream(FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
return buffer;
}
}
}
}
public static class StructuredStorageUtils
{
[DllImport("ole32.dll")]
static extern int StgIsStorageFile(
[MarshalAs(UnmanagedType.LPWStr)]
string pwcsName);
public static bool IsFileStucturedStorage(string fileName)
{
int res = StgIsStorageFile(fileName);
if (res == 0)
return true;
if (res == 1)
return false;
throw new FileNotFoundException("File not found", fileName);
}
}
public class StructuredStorageException : Exception
{
public StructuredStorageException()
{
}
public StructuredStorageException(string message)
: base(message)
{
}
public StructuredStorageException(string message, Exception innerException)
: base(message, innerException)
{
}
}
public class StructuredStorageRoot : IDisposable
{
StorageInfo _storageRoot;
public StructuredStorageRoot(Stream stream)
{
try
{
_storageRoot = (StorageInfo)InvokeStorageRootMethod(null,
"CreateOnStream",
stream);
}
catch (Exception ex)
{
throw new StructuredStorageException("Cannot get StructuredStorageRoot", ex);
}
}
public StructuredStorageRoot(string fileName)
{
try
{
_storageRoot = (StorageInfo)InvokeStorageRootMethod(null,
"Open", fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
}
catch (Exception ex)
{
throw new StructuredStorageException("Cannot get StructuredStorageRoot", ex);
}
}
private static object InvokeStorageRootMethod(StorageInfo storageRoot, string methodName, params object[] methodArgs)
{
Type storageRootType = typeof(StorageInfo).Assembly.GetType("System.IO.Packaging.StorageRoot", true, false);
object result = storageRootType.InvokeMember(methodName,
BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
null, storageRoot, methodArgs);
return result;
}
private void CloseStorageRoot()
{
InvokeStorageRootMethod(_storageRoot, "Close");
}
#region Implementation of IDisposable
public void Dispose()
{
CloseStorageRoot();
}
#endregion
public StorageInfo BaseRoot
{
get { return _storageRoot; }
}
}
public struct BasicFileInfo
{
public Int32 A { get; set; }
public Int32 B { get; set; }
public Int16 C { get; set; }
public string Path1 { get; set; }
public string Version { get; set; }
public string Path2 { get; set; }
public string Data { get; set; }
public byte[] Unknown { get; set; }
public string UID { get; set; }
public string Localization { get; set; }
}
}