Inventor文件中保存自定义数据 - 3

前面我们了解了可以通过iProperties或Attribute为文档附加数据。由于Inventor 文件也是一种Windows文件,因此Windows提供的附加数据方法也适用。那就是 IStorage & IStream. 在全球博客上,我已经撰写了专门的文章介绍。不过是用C++写的。
 How to use private storage and stream in C++

后来我琢磨着如何用.NET写。前几个月,正好论坛上有人问起,我就花时间去研究。最后,创建是没问题,可读取却总是失败,见论坛讨论:

http://forums.autodesk.com/t5/Autodesk-Inventor-Customization/Store-object-inside-document/td-p/3610956

百思不得其解。由于忙于DevDays,就暂时放下了。这几天重新翻出来,有请我们开发部的同事Mona帮忙看看。她发现问题出在创建IStorage后,没有释放。于是第二次访问(例如读取)就发生失败了。而C++代码比较幸运,用的是智能指针,自动释放了。这真是太有帮助的发现了!基于此,对代码稍作修改,就运行正常了!再次特别感谢Mona,还有两个网上文章:

 http://www.pinvoke.net/default.aspx/Enums/STGM.html 
http://bytes.com/topic/c-sharp/answers/760093-accessing-com-c-istream-parameter


以下是代码样例,测试可打开一个现有文档,执行test,先是创建数据,添加到文档,接着读取出来。

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]

        public enum STGM : 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)

                    return false;

 

                // 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)

                    return false ;

 

                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);

 

                return true;

            }

            catch (Exception ex)

            {

                MessageBox.Show(ex.ToString());

                return false;

            }

        }

 

        // read the storge and stream

        bool ReadPrivateStorageAndStream(Document pDoc,

            string StorageName,

            string StreamName,

              out string  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)

                    return false;

 

                // 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)

                    return false;

 

                byte[] byteVsize = new byte[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 =

                    new byte[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);

                return true 

            }

            catch (Exception ex)

            {

            MessageBox.Show(ex.ToString());               

                return false;

            }

 

        }

 

        // main function to test

        private void 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);

            }

        }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值