Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

Saving Metadata in Document File without changing DbRevisionId or RevisionId

guilloryt
Advocate

Saving Metadata in Document File without changing DbRevisionId or RevisionId

guilloryt
Advocate
Advocate

Morning,

 

Last week I posted ... "We are working on a project to generate inventor documents  from master "templates" parametrically (similar to iparts) using both iLogic and the api. I am looking for some technique/method to fully qualify if "any edits" have been made to the document after it was generated."

 

At that time I thinking of trying to calc a checksum and looking for some method to embedded the checksum in the doc file. Adam Nagy suggested using the document RevisionId and DatabaseRevisionId to qualify if any edits had been made. Turns ou that works quite nicely.

 

However I am still evaluationg the best method to embed these values (and also a larger serailized config file) into the file.

 

Did find several articles related to "Save extra data in Inventor file" by Xiaodong Liang on http://adndevblog.typepad.com/manufacturing/2013/03/save-extra-data-in-inventor-file-1.html

 

He details three methods available.. 1. iProperties 2. Attribute 3. IStorage & IStream

 

Did a bit of testing trying each of these techniques to save my metadata.

 

In my test it seems that using Attributes or iStorage requires a full document save.. which changes the DatabaseRevisionId and RevisionId. Which for my purposes is not ideal. 

 

However did find when using the Custom Property Set and Apprentice FlushToFile to push the properties to the document file the DbRevisionId and RevisionId are not changed.  For my purpsose this seems ideal.. but  would like to confirm my assumptions before pressing on.

 

Could anyone confirm that if using Apprentiice PropertySet.FlushToFile with a Custom PropertySet will "never"change the DbRevisionId and RevisionId of the document?

 

My second questions is "how much data can each property in the property set contain"?

 

Reason for second question is I am considering using this propertyset to also store a larger set of data.. serialized configuration data for the app. Did a quick test and  a singe property appearred to accept 100k of data.. but 1 mb it fell over. Possibly I can break the serialize string into chunks to store it in the property sets.

 

I would think that iStorage/Attributes would be really designed to store larger sets of data... But if Custom PropertySets don't effect RevisionId then I think it would be my first choice.

 

 

Thanks

 

 

 

0 Likes
Reply
988 Views
5 Replies
Replies (5)

adam.nagy
Autodesk Support
Autodesk Support

Hi,

 

Your finding concerning Apprentice could be correct, but I need to double-check with others.

 

And concerning using IStorage and you saying that "iStorage requires a full document save". The last paragraph in this blog post already mentions that you can modify those data without using Inventor. Here is another article related to that:

http://adndevblog.typepad.com/manufacturing/2014/04/save-extra-data-in-inventor-file-without-invento...

 

Cheers, 



Adam Nagy
Autodesk Platform Services
0 Likes

guilloryt
Advocate
Advocate

Afternoon Adam,

 

In my testing with iStorage in .net the data was not committed to the file unless I made set the dirty flag and did doc.Save.

 

The c++ code really is only a mistery to me... But see below the code I converted from your c# example to vb...

 

 

Is there another method I could use with VB to commit?

 

 

 

 

Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports System.Reflection
Imports Inventor
Imports System.Diagnostics
Imports MVOI = Microsoft.VisualStudio.OLE.Interop
Imports Newtonsoft.Json
Imports Cameron.FOP.ModelCF

Public Class InvDoc_Storage
Public Enum STGM As Integer
DIRECT = &H0
TRANSACTED = &H10000
SIMPLE = &H8000000
READ = &H0
WRITE = &H1
READWRITE = &H2
SHARE_DENY_NONE = &H40
SHARE_DENY_READ = &H30
SHARE_DENY_WRITE = &H20
SHARE_EXCLUSIVE = &H10
PRIORITY = &H40000
DELETEONRELEASE = &H4000000
NOSCRATCH = &H100000
CREATE = &H1000
CONVERT = &H20000
FAILIFTHERE = &H0
NOSNAPSHOT = &H200000
DIRECT_SWMR = &H400000
End Enum

' create private storage and stream
Private Function CreatePrivateStorageAndStream(pDoc As Inventor.Document, StorageName As String, StreamName As String, data As String) As Boolean
Try
' create/get storage. "true" means if create
'if it does not exists.
Dim pStg As MVOI.IStorage = DirectCast(pDoc.GetPrivateStorage(StorageName, True), MVOI.IStorage)
If pStg Is Nothing Then
Return False
End If

' create stream in the storage
Dim pStream As MVOI.IStream = Nothing
pStg.CreateStream(StreamName, CUInt(STGM.DIRECT Or STGM.CREATE Or STGM.READWRITE Or STGM.SHARE_EXCLUSIVE), 0, 0, pStream)

If pStream Is Nothing Then
Return False
End If

Dim byteVsize As Byte() = System.BitConverter.GetBytes(data.Length)
Dim byteVData As Byte() = Encoding.[Default].GetBytes(data)
Dim dummy As UInteger

' convert string to byte and store it to the stream
pStream.Write(byteVsize, CUInt(4), dummy)
pStream.Write(byteVData, CUInt(byteVData.Length), dummy)

' Save the data
pStream.Commit(CUInt(MVOI.STGC.STGC_OVERWRITE Or MVOI.STGC.STGC_DEFAULT))

'Don't forget to commit changes also in storage
pStg.Commit(CUInt(MVOI.STGC.STGC_DEFAULT Or 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 ex As Exception
MessageBox.Show(ex.ToString())
Return False
End Try
End Function
' read the storge and stream
Private Function ReadPrivateStorageAndStream(pDoc As Inventor.Document, StorageName As String, StreamName As String, ByRef outDataStr As String) As Boolean
outDataStr = ""
Try
'get the storge. "false" means do not create
'if it does not exist
Dim pStg As MVOI.IStorage = DirectCast(pDoc.GetPrivateStorage(StorageName, False), MVOI.IStorage)
If pStg Is Nothing Then
Return False
End If

' open stream to read
Dim pStream As MVOI.IStream = Nothing
pStg.OpenStream(StreamName, IntPtr.Zero, CUInt(STGM.DIRECT Or STGM.READWRITE Or STGM.SHARE_EXCLUSIVE), 0, pStream)

If pStream Is Nothing Then
Return False
End If

Dim byteVsize As Byte() = New Byte(15) {}
Dim intSize As UInteger = 4

' read the stream
Dim dummy As UInteger
pStream.Read(byteVsize, CUInt(intSize), dummy)
Dim lSize As Integer = System.BitConverter.ToInt16(byteVsize, 0)

Dim outDataByte As Byte() = New Byte(8191) {}
pStream.Read(outDataByte, CUInt(lSize), 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 ex As Exception
MessageBox.Show(ex.ToString())
Return False
End Try

End Function

0 Likes

adam.nagy
Autodesk Support
Autodesk Support

Hi,

 

This is the feedback I got from engineering:

>>>>>

Using FlushToFile via Apprentice to update iProperties won’t modify the DatabaseRevisionId(this will be changed for reference changes, geometry changes, etc, but not for file property change),  but the RevisionId will be changed.

<<<<<

 

So if you want to keep RevisionId unchanged as well then I think you'll have to go with structured storage editing.

 

"In my testing with iStorage in .net the data was not committed to the file unless I made set the dirty flag and did doc.Save."

But in that case you are accessing the storage through the Inventor API, and I think that makes the difference. As shown in the C++ sample you can modify the structured storage data without using any Inventor API - Inventor does not even need to be installed in order to modify the structured data.
Structured storage is a Microsoft technology independent of Inventor.

 

Cheers,



Adam Nagy
Autodesk Platform Services
0 Likes

guilloryt
Advocate
Advocate

In my testing verified that the RevisionId  is changed when I use flushtofile if I update one of the standard inventor property sets.

 

But seems when I add a new user defined property set and update it with flushtofile neither the neither RevisionId nor DatabaseRevisionId is changed. 

 

Would it correct to assume going forwar that if I am only updating user defined property sets that neither the RevisionId/DatabaseRevisionId will change when I update with flushtofile?

0 Likes

adam.nagy
Autodesk Support
Autodesk Support

I haven't got feedback yet from my colleague concerning your last comment.

But if that's how it works, then that's how it works and I don't expect it to change, but we cannot promise something like that.

You'll just have to make sure it's part of your tests to check that everything works the same in the next release.

 

If you used the Structured Storage library directly, I think that would be the safest, and that would work on any computer - with or without Inventor installed. 



Adam Nagy
Autodesk Platform Services
0 Likes