作为 利用IStorage和IStream存储自定义数据到Inventor文件 (C++)的姊妹篇,这里讨论如何用.NET实现。全球博客还提到了研究出这段代码的曲折过程,此处就略过三千字了,呵呵
http://adndevblog.typepad.com/manufacturing/2013/03/save-extra-data-in-inventor-file-3.html
直奔主题,以下代码演示了如何对某文档进行IStorage和Istream的创建和访问。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;
using Inventor;
using System.Diagnostics;
using MVOI = Microsoft.VisualStudio.OLE.Interop;
//enum flags for STGM
[Flags]
publicenumSTGM : int
{
DIRECT = 0x00000000,
TRANSACTED = 0x00010000,
SIMPLE = 0x08000000,
READ = 0x00000000,
WRITE = 0x00000001,
READWRITE = 0x00000002,
SHARE_DENY_NONE = 0x00000040,
SHARE_DENY_READ = 0x00000030,
SHARE_DENY_WRITE = 0x00000020,
SHARE_EXCLUSIVE = 0x00000010,
PRIORITY = 0x00040000,
DELETEONRELEASE = 0x04000000,
NOSCRATCH = 0x00100000,
CREATE = 0x00001000,
CONVERT = 0x00020000,
FAILIFTHERE = 0x00000000,
NOSNAPSHOT = 0x00200000,
DIRECT_SWMR = 0x00400000,
}
// create private storage and stream
bool CreatePrivateStorageAndStream(Document pDoc,
string StorageName,
string StreamName,
string data)
{
try
{
// create/get storage. "true" means if create
//if it does not exists.
MVOI.IStorage pStg =
(MVOI.IStorage)pDoc.GetPrivateStorage
(StorageName, true);
if (pStg == null)
returnfalse;
// create stream in the storage
MVOI.IStream pStream = null;
pStg.CreateStream(StreamName, (uint)
(STGM.DIRECT | STGM.CREATE |
STGM.READWRITE | STGM.SHARE_EXCLUSIVE),
0, 0, out pStream);
if (pStream == null)
returnfalse ;
byte[] byteVsize =
System.BitConverter.GetBytes
(data.Length);
byte[] byteVData =
Encoding.Default.GetBytes(data);
uint dummy;
// convert string to byte and store it to the stream
pStream.Write(byteVsize,
(uint)(sizeof(int)),
out dummy);
pStream.Write(byteVData,
(uint)(byteVData.Length),
out dummy);
// Save the data
pStream.Commit((uint)
(MVOI.STGC.STGC_OVERWRITE |
MVOI.STGC.STGC_DEFAULT));
//Don't forget to commit changes also in storage
pStg.Commit((uint)(MVOI.STGC.STGC_DEFAULT |
MVOI.STGC.STGC_OVERWRITE));
// force document to be dirty thus
// the change can be saved when document
//is saved.
pDoc.Dirty = true;
pDoc.Save();
//Don't forget to release the object!!
Marshal.ReleaseComObject(pStg);
returntrue;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
returnfalse;
}
}
// read the storge and stream
bool ReadPrivateStorageAndStream(Document pDoc,
string StorageName,
string StreamName,
outstring outDataStr)
{
outDataStr = "";
try
{
//get the storge. "false" means do not create
//if it does not exist
MVOI.IStorage pStg =
(MVOI.IStorage)pDoc.GetPrivateStorage
(StorageName, false);
if (pStg == null)
returnfalse;
// open stream to read
MVOI.IStream pStream = null;
pStg.OpenStream(StreamName,IntPtr.Zero,
(uint)(STGM.DIRECT| STGM.READWRITE |
STGM.SHARE_EXCLUSIVE),
0, out pStream);
if (pStream == null)
returnfalse;
byte[] byteVsize = newbyte[16];
uint intSize = sizeof(int);
// read the stream
uint dummy;
pStream.Read(byteVsize,
(uint)intSize, out dummy);
int lSize = System.BitConverter.ToInt16
(byteVsize,0);
byte[] outDataByte =
newbyte[8192];
pStream.Read(outDataByte,
(uint)lSize, out dummy);
// convert byte to string
outDataStr =
Encoding.Default.GetString(outDataByte,
0, lSize);
//Don't forget to release the object!!
Marshal.ReleaseComObject(pStg);
returntrue;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
returnfalse;
}
}
// main function to test
privatevoid test()
{
//get Inventor application
string progId = "Inventor.Application";
Inventor.Application m_inventorApp =
(Inventor.Application)Marshal.GetActiveObject
(progId );
//get the current document.
Document pDoc = m_inventorApp.ActiveDocument;
//create the storage and stream
bool Result = CreatePrivateStorageAndStream
(pDoc,
"MyPrvStorage1",
"MyStream1",
"Some private stored data");
if (Result)
{
pDoc = m_inventorApp.ActiveDocument;
string outPutStr = null;
//read the storage and stream
bool readResult = ReadPrivateStorageAndStream
(pDoc,
"MyPrvStorage1",
"MyStream1", out outPutStr);
MessageBox.Show(outPutStr);
}
}