none
How to read document properties such as Title, Author by using IFilter RRS feed

  • Question

  • I have a Microsoft word document (test.docx) with the text "test for full text search". The document has the following properties

    Title : "SRK Document"

    Author: "ramakrishnan"

    The document is stored in the SQL Server 2005 database as image column.

    Now I want to read the data from SQL server database and use the IFilter to read document properties.

    Note:

    Document content can be read by using the IFilters. Further details can be found in

    http://www.codeproject.com/KB/cs/IFilterReader.aspx

    Thanks & Regards

    Ramakrishnan S

     


    • Moved by Jackie-Sun Tuesday, June 7, 2011 9:07 AM (From:Visual C# General)
    Thursday, June 2, 2011 4:39 AM

Answers

  • Hi,

    The properties can be read using the code given in the following link with slight modifications.

    http://www.codeproject.com/KB/cs/IFilter.aspx

    Add the following code to Read(char[] array, int offset, int count) method

     if (_currentChunk.flags == CHUNKSTATE.CHUNK_VALUE)
          {
            // Need complete code to do ifilt.GetValue()
            IntPtr pointer = new IntPtr();
    
            _filter.GetValue(ref pointer);
    
            PROPVARIANT propVariant;
            try
            {
              propVariant = (PROPVARIANT)Marshal.PtrToStructure(new IntPtr((long)pointer.ToInt64()), typeof(PROPVARIANT));
            }
            catch
            {
              continue;
            }
    
            string propertyName = _currentChunk.attribute.guidPropSet.ToString() + ":";
            if (_currentChunk.attribute.psProperty.ulKind == 0)
              propertyName += Marshal.PtrToStringAuto(_currentChunk.attribute.psProperty.lpwstr);
            else
              propertyName += _currentChunk.attribute.psProperty.propid.ToString();
    
            object propertyValue = GetValueFromPropVariant(propVariant);
            if (propertyValue != null && !(propertyValue is System.Runtime.InteropServices.FILETIME))
            {
              _properties += propertyValue.ToString() + " ";
            }
          }
    


    Add the following support method

    private static object GetValueFromPropVariant(PROPVARIANT propvariant)
       {
         switch (propvariant.vt)
         {
           case VT_TYPE.VT_EMPTY:
           case VT_TYPE.VT_NULL: return null;
           case VT_TYPE.VT_I1: return propvariant.cVal; //cVal 1-byte signed integer.
           case VT_TYPE.VT_UI1: return propvariant.bVal;
           case VT_TYPE.VT_I2: return propvariant.iVal;
           case VT_TYPE.VT_UI2: return propvariant.uiVal;
           case VT_TYPE.VT_I4: return propvariant.lVal;
           case VT_TYPE.VT_UI4: return propvariant.ulVal;
           case VT_TYPE.VT_INT: return propvariant.intVal;
           case VT_TYPE.VT_UINT: return propvariant.uintVal;
           case VT_TYPE.VT_I8: return propvariant.hVal;
           case VT_TYPE.VT_UI8: return propvariant.uhVal;
           case VT_TYPE.VT_R4: return propvariant.fltVal;
           case VT_TYPE.VT_R8: return propvariant.dblVal;
           case VT_TYPE.VT_BOOL: return propvariant.boolVal;
           case VT_TYPE.VT_ERROR: return propvariant.scode;
           case VT_TYPE.VT_CY: return "Money";
           case VT_TYPE.VT_DATE: return propvariant.date;
           case VT_TYPE.VT_FILETIME: return propvariant.filetime;
           case VT_TYPE.VT_LPSTR: return Marshal.PtrToStringAnsi(propvariant.other);
           case VT_TYPE.VT_LPWSTR: return Marshal.PtrToStringUni(propvariant.other);
           default: return null;
         }
       }
    


    Change the PROPVARINAT enum to

    [StructLayout(LayoutKind.Explicit)]
     public struct PROPVARIANT
     {
       [FieldOffset(0)]
       public VT_TYPE vt;
       [FieldOffset(2)]
       public short wReserved1;
       [FieldOffset(4)]
       public short wReserved2;
       [FieldOffset(6)]
       public short wReserved3;
       [FieldOffset(8)]
       public sbyte cVal;
       [FieldOffset(8)]
       public byte bVal;
       [FieldOffset(8)]
       public short iVal;
       [FieldOffset(8)]
       public ushort uiVal;
       [FieldOffset(8)]
       public int lVal;
       [FieldOffset(8)]
       public uint ulVal;
       [FieldOffset(8)]
       public int intVal;
       [FieldOffset(8)]
       public uint uintVal;
       [FieldOffset(8)]
       public long hVal;
       [FieldOffset(8)]
       public ulong uhVal;
       [FieldOffset(8)]
       public float fltVal;
       [FieldOffset(8)]
       public double dblVal;
       /*[MarshalAs(UnmanagedType.Currency)]
       [FieldOffset(8)]
       public Decimal cyVal;*/
       [FieldOffset(8)]
       public DateTime date;
       [MarshalAs(UnmanagedType.VariantBool)]
       [FieldOffset(8)]
       public bool boolVal;
       [MarshalAs(UnmanagedType.Error)]
       [FieldOffset(8)]
       public int scode;
       [FieldOffset(8)]
       public FILETIME filetime;
       [FieldOffset(8)]
       public IntPtr other;
     }
    

    Thanks & Regards

    Ramakrishnan S

    Friday, July 1, 2011 2:12 PM

All replies

  • Check below Property there is Sample for iProperty Usage.

    http://www.codeproject.com/Answers/143445/How-to-use-ipropertystorage.aspx#answer3


    Please "Mark as Answer" if this post answered your question. :)

    Kalpesh Chhatrala | Software Developer | Rajkot | India

    Kalpesh 's Blog

    VFP Form to C#, Vb.Net Conversion Utility
    Thursday, June 2, 2011 4:56 AM
  • Hello Ramakrishnan,

    Thanks for your post.

    Yes, Kalpesh gives you a very useful article, and this can indeed ansswer your question. Also, I found another method to do this. The document is provided by MSDN Library, 2007 Microsoft Office system documents allow you to set and retrieve custom document properties, so that you can store your own document metadata.

    Please see more information at here:

    http://msdn.microsoft.com/en-us/library/bb308936.aspx

    Hope this can help.

     

    Good day,


    Jackie Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, June 3, 2011 6:06 AM
  • Hi Kalpesh and Jackie Sun,

    i'll look into the options suggested by you and update you soon.

    Thanks & Regards

    Ramakrishnan S

     

     

    Friday, June 3, 2011 6:23 AM
  • Some of Components can read document properties without ole automation, You can try Spire.Doc, I used it, work well.

    Friday, June 3, 2011 8:10 AM
  • Hi Ramakrishnan,

    How about your issue? Do you have any update? I'm waiting for you.

     

    Good day,


    Jackie Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, June 6, 2011 6:52 AM
  • Hi Jackie Sun,

    I've tried the solution suggested by Kalpesh from the below link. I also got the same error.

    http://www.codeproject.com/Answers/143445/How-to-use-ipropertystorage.aspx#answer3

    Thanks & Reagrds

    Ramakrishnan S

    Monday, June 6, 2011 9:45 AM
  • Hi ,

    Thanks for your feedbacks.

    The reason you got the exception is that the program is trying to access a member of a reference type variable which is set to null.

    Since I don't know your code, but I suggest that you to use a "if" block to make a judgment that your reference of object != null, like this as below:

    if (problem.ProblemMethod() != null)
    {
      // return value is non-null
      problem.ProblemMethod().Trim();  
    } 

    I hope this can help you.

     

    Good day,


    Jackie Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, June 7, 2011 6:21 AM
  • Hi Jackie Sun,

    Thanks for your reply. I'm getting the following exception "could not be found. (Exception from HRESULT: 0x80030002 (STG_E_FILENOTFOUND))" when excuting the following statement

    int hresult2 = propSetStorage.Open(ref fmtid_SummaryProperties,
                        (int)(STGM.DIRECT | STGM.SHARE_EXCLUSIVE),
                        out propStorage);

    Note: The physical file exits in the specified location. Please find the code below for your reference.

    Calling Code:

     private void button1_Click(object sender, EventArgs e) {
          //FileAttributes fileAttributes = File.GetAttributes("c:\\testdocument.docx");
          //FileInfo fs = new FileInfo("c:\\testdocument.docx");
    
          FileSummary summary = new FileSummary(new
          System.IO.FileInfo("c:\\testdocument.docx"));
          MessageBox.Show(summary.GetProperty(SummaryPropId.Author));
          MessageBox.Show(summary.GetProperty(SummaryPropId.Title));
        }
    

    FileSummary Code:

    namespace IFilterSummaryProperty {
      using System;
      using System.Text;
      using System.Runtime.InteropServices;
      using System.IO;
    
      namespace StructuredStorageWrapper {
        public enum SummaryPropId : int {
          Title = 0x00000002,
          Subject = 0x00000003,
          Author = 0x00000004,
          Keywords = 0x00000005,
          Comments = 0x00000006,
          Template = 0x00000007,
          LastSavedBy = 0x00000008,
          RevisionNumber = 0x00000009,
          TotalEditingTime = 0x0000000A,
          LastPrinted = 0x0000000B,
          CreateDateTime = 0x0000000C,
          LastSaveDateTime = 0x0000000D,
          NumPages = 0x0000000E,
          NumWords = 0x0000000F,
          NumChars = 0x00000010,
          Thumbnail = 0x00000011,
          AppName = 0x00000012,
          Security = 0x00000013
        }
    
        public enum STGC : int {
          DEFAULT = 0,
          OVERWRITE = 1,
          ONLYIFCURRENT = 2,
          DANGEROUSLYCOMMITMERELYTODISKCACHE = 4,
          CONSOLIDATE = 8
        }
    
        public enum PROPSETFLAG : int {
          DEFAULT = 0,
          NONSIMPLE = 1,
          ANSI = 2,
          UNBUFFERED = 4,
          CASE_SENSITIVE = 8
        }
    
        public enum STGM : int {
          READ = 0x00000000,
          WRITE = 0x00000001,
          READWRITE = 0x00000002,
          SHARE_DENY_NONE = 0x00000040,
          SHARE_DENY_READ = 0x00000030,
          SHARE_DENY_WRITE = 0x00000020,
          SHARE_EXCLUSIVE = 0x00000010,
          PRIORITY = 0x00040000,
          CREATE = 0x00001000,
          CONVERT = 0x00020000,
          FAILIFTHERE = 0x00000000,
          DIRECT = 0x00000000,
          TRANSACTED = 0x00010000,
          NOSCRATCH = 0x00100000,
          NOSNAPSHOT = 0x00200000,
          SIMPLE = 0x08000000,
          DIRECT_SWMR = 0x00400000,
          DELETEONRELEASE = 0x04000000
        }
    
        public enum STGFMT : int {
          STORAGE = 0,
          FILE = 3,
          ANY = 4,
          DOCFILE = 5
        }
    
        [StructLayout(LayoutKind.Explicit, Size = 8, CharSet = CharSet.Unicode)]
        public struct PropSpec {
          [FieldOffset(0)]
          public int ulKind;
          [FieldOffset(4)]
          public IntPtr Name_Or_ID;
        }
    
        [StructLayout(LayoutKind.Explicit, Size = 16)]
        public struct PropVariant {
          [FieldOffset(0)]
          public short variantType;
          [FieldOffset(8)]
          public IntPtr pointerValue;
          [FieldOffset(8)]
          public byte byteValue;
          [FieldOffset(8)]
          public long longValue;
    
          public void FromObject(object obj) {
            if (obj.GetType() == typeof(string)) {
              this.variantType = (short)VarEnum.VT_LPWSTR;
              this.pointerValue = Marshal.StringToHGlobalUni((string)obj);
            }
          }
        }
    
        [ComVisible(true), ComImport(),
        Guid("0000013A-0000-0000-C000-000000000046"),
        InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IPropertySetStorage {
          uint Create(
            [In] ref System.Guid rfmtid,
            [In] IntPtr pclsid,
            [In] int grfFlags,
            [In] int grfMode,
            ref IPropertyStorage propertyStorage);
    
          int Open(
            [In] ref System.Guid rfmtid,
            [In] int grfMode,
            [Out] out IPropertyStorage propertyStorage);
        }
    
        [ComVisible(true), ComImport(),
        Guid("00000138-0000-0000-C000-000000000046"),
        InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IPropertyStorage {
          int ReadMultiple(
            uint numProperties,
            [MarshalAs(UnmanagedType.LPArray)] PropSpec[] propertySpecifications,
            [MarshalAs(UnmanagedType.LPArray)] PropVariant[] propertyValues);
    
          int WriteMultiple(
            uint numProperties,
            [MarshalAs(UnmanagedType.Struct)] ref PropSpec
            propertySpecification,
            ref PropVariant propertyValues,
            int propIDNameFirst);
    
          uint Commit(
            int commitFlags);
        }
    
        public enum HResults : uint {
          S_OK = 0,
          STG_E_FILEALREADYEXISTS = 0x80030050
        }
    
        public class ole32 {
          [StructLayout(LayoutKind.Explicit, Size = 12,
             CharSet = CharSet.Unicode)]
          public struct STGOptions {
            [FieldOffset(0)]
            ushort usVersion;
            [FieldOffset(2)]
            ushort reserved;
            [FieldOffset(4)]
            uint uiSectorSize;
            [FieldOffset(8), MarshalAs(UnmanagedType.LPWStr)]
            string
              pwcsTemplateFile;
          }
    
          [DllImport("ole32.dll", CharSet = CharSet.Unicode)]
          public static extern uint StgCreateStorageEx(
            [MarshalAs(UnmanagedType.LPWStr)] string name,
            int accessMode, int storageFileFormat, int fileBuffering,
            IntPtr options, IntPtr reserved, ref System.Guid riid,
            [MarshalAs(UnmanagedType.Interface)] ref IPropertySetStorage
            propertySetStorage);
    
          [DllImport("ole32.dll", CharSet = CharSet.Unicode)]
          public static extern uint StgOpenStorageEx(
            [MarshalAs(UnmanagedType.LPWStr)] string name,
            int accessMode, int storageFileFormat, int fileBuffering,
            IntPtr options, IntPtr reserved, ref System.Guid riid,
            [MarshalAs(UnmanagedType.Interface)] ref IPropertySetStorage
            propertySetStorage);
        }
    
        public class FileSummary {
          private FileInfo m_fileInfo;
          public FileSummary(FileInfo fileInfo) {
            m_fileInfo = fileInfo;
            //m_fileInfo.Open(FileMode.Open,FileAccess.ReadWrite,FileShare.ReadWrite);
    
          }
    
          public void SetProperty(SummaryPropId summaryPropertID, string value) {
            // Open the file and its property set stream
            IPropertySetStorage propSetStorage = null;
            Guid IID_PropertySetStorage = new
              Guid("0000013A-0000-0000-C000-000000000046");
    
            uint hresult = ole32.StgOpenStorageEx(m_fileInfo.FullName,
              (int)(STGM.SHARE_EXCLUSIVE | STGM.READWRITE),
              (int)STGFMT.FILE,
              0,
              (IntPtr)0,
              (IntPtr)0,
              ref IID_PropertySetStorage,
              ref propSetStorage);
    
            // Open the Summary Information property set
            Guid fmtid_SummaryProperties = new
              Guid("F29F85E0-4FF9-1068-AB91-08002B27B3D9");
            IPropertyStorage propStorage = null;
    
            int hresult2 = propSetStorage.Open(
              ref fmtid_SummaryProperties,
              (int)(STGM.SIMPLE | STGM.READWRITE | STGM.SHARE_EXCLUSIVE),
              out propStorage);
    
            // Assemble a property descriptor for the specified property
            PropSpec propertySpecification = new PropSpec();
            propertySpecification.ulKind = 1;
            propertySpecification.Name_Or_ID = new
              IntPtr((int)summaryPropertID);
    
            //Set the value wanted in a property variant
            PropVariant propertyValue = new PropVariant();
            propertyValue.FromObject(value);
    
            // Pass the property spec and its new value to the  WriteMultiplemethod
            propStorage.WriteMultiple(1, ref propertySpecification, ref
            propertyValue, 0);
    
            // Commit Changes
            hresult = propStorage.Commit((int)STGC.DEFAULT);
    
            // Release the Com objects
            Marshal.ReleaseComObject(propStorage);
            Marshal.ReleaseComObject(propSetStorage);
            propStorage = null;
            propSetStorage = null;
    
          }
    
          public string GetProperty(SummaryPropId summaryPropertID) {
            // Open the file and its property set stream
            IPropertySetStorage propSetStorage = null;
            Guid IID_PropertySetStorage = new
              Guid("0000013A-0000-0000-C000-000000000046");
    
            uint hresult = ole32.StgOpenStorageEx(m_fileInfo.FullName,
              (int)(STGM.DIRECT_SWMR | STGM.READ | STGM.SHARE_DENY_NONE),
              (int)STGFMT.FILE,
              0,
              System.IntPtr.Zero,
              System.IntPtr.Zero,
              ref IID_PropertySetStorage,
              ref propSetStorage);
    
            // Open the Summary Information property set
            Guid fmtid_SummaryProperties = new
              Guid("F29F85E0-4FF9-1068-AB91-08002B27B3D9");
            IPropertyStorage propStorage = null;
    
    
            int hresult2 = propSetStorage.Open(
              ref fmtid_SummaryProperties,
              (int)(STGM.DIRECT | STGM.SHARE_EXCLUSIVE),
              out propStorage);
    
            // Specify the property to be retrieved
            PropSpec[] propSpecs = new PropSpec[1];
            propSpecs[0].ulKind = 1;
            propSpecs[0].Name_Or_ID = new IntPtr((int)summaryPropertID);
            PropVariant[] propertyValues = new PropVariant[1];
    
            // Retrieve the value      
            hresult2 = propStorage.ReadMultiple(1, propSpecs, propertyValues);
    
            // Release the Com objects
            Marshal.ReleaseComObject(propStorage);
            Marshal.ReleaseComObject(propSetStorage);
            propStorage = null;
            propSetStorage = null;
    
            return Marshal.PtrToStringUni(propertyValues[0].pointerValue);
    
          }
    
        }
      }
    }
    
    

    Thanks & Regards

    Ramakrishnan S

    Tuesday, June 7, 2011 6:52 AM
  • Hi, I am moving it to Word For Developor Forum for better support. Thanks,
    Jackie Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, June 7, 2011 9:11 AM
  • Document Properties are stored in completely different ways depending on whether the document is a .doc or a .docx.

    The code you posted is looking at OLE Structured Storage files, which is how .docs (at least Word 97-2011 .docs) are stored. But it has no chance of working with .docx, because that consists of a Zipped set of XML format files, not an OLE SS file. I don't know whether MS provides any stuff specifically to help you use IFilter with that file type.

    For this purpose, your best bet is probably to use the Open XML API to get content from the .docx files - I don't have code for that, but a search may help. Be aware that there are now several types of "property" in a Word document (or things that could be considered properties) - the storage of "Built in" properties and the type of property you are looking at ("Custom Document properties") is fairly straightforward. The storage of properties created in e.g. SharePoint is more complex.

     


    Peter Jamieson
    Tuesday, June 7, 2011 9:36 AM
  • Hi All,

    I think we have deviated from my original post on Thursday, June 02, 2011 4:39 AM. 

    The file content will be passed as bytes to the IFilter. Please refere to the below link

    http://www.codeproject.com/KB/cs/IFilterReader.aspx

    So, by using the IFilters i need to get the document properties.

    Note:

    1. File will not be stored physically. The content will be passed as bytes from SQL server.

    2. I'm able to get the document content

    Thanks & Regards

    Ramakrishnan S

     

    Tuesday, June 7, 2011 9:49 AM
  • There's an incomplete example by Steve McMahon at

    http://vbaccelerator.com/article.asp?id=12330

    If you open the solution, then

     a. put your own .docx filename in the first line of the button1_Click code in form1.cs

     b. make it a Console Application so you can see Console output

     c. uncomment the commented block under else if (stat.flags == CHUNKSTATE.CHUNK_VALUE) 

    and other Console.WriteLine statements

     d. run the solution, click Button1, and watch the console output

    you should have a starting point as to how to extract the document properties for a DOCX.

    As I understand it, for a .DOC, it is the filter itself that returns a value saying that you have to go and look at the original file and open the Property Storage there

    Sorry, I am not able to take it any further than that.

     


    Peter Jamieson
    • Proposed as answer by Bruce Song Tuesday, June 21, 2011 1:55 PM
    Tuesday, June 7, 2011 3:58 PM
  • Hmm, looks like there could be some malware on that site :-(
    Peter Jamieson
    Tuesday, June 7, 2011 4:28 PM
  • Hi,

    The properties can be read using the code given in the following link with slight modifications.

    http://www.codeproject.com/KB/cs/IFilter.aspx

    Add the following code to Read(char[] array, int offset, int count) method

     if (_currentChunk.flags == CHUNKSTATE.CHUNK_VALUE)
          {
            // Need complete code to do ifilt.GetValue()
            IntPtr pointer = new IntPtr();
    
            _filter.GetValue(ref pointer);
    
            PROPVARIANT propVariant;
            try
            {
              propVariant = (PROPVARIANT)Marshal.PtrToStructure(new IntPtr((long)pointer.ToInt64()), typeof(PROPVARIANT));
            }
            catch
            {
              continue;
            }
    
            string propertyName = _currentChunk.attribute.guidPropSet.ToString() + ":";
            if (_currentChunk.attribute.psProperty.ulKind == 0)
              propertyName += Marshal.PtrToStringAuto(_currentChunk.attribute.psProperty.lpwstr);
            else
              propertyName += _currentChunk.attribute.psProperty.propid.ToString();
    
            object propertyValue = GetValueFromPropVariant(propVariant);
            if (propertyValue != null && !(propertyValue is System.Runtime.InteropServices.FILETIME))
            {
              _properties += propertyValue.ToString() + " ";
            }
          }
    


    Add the following support method

    private static object GetValueFromPropVariant(PROPVARIANT propvariant)
       {
         switch (propvariant.vt)
         {
           case VT_TYPE.VT_EMPTY:
           case VT_TYPE.VT_NULL: return null;
           case VT_TYPE.VT_I1: return propvariant.cVal; //cVal 1-byte signed integer.
           case VT_TYPE.VT_UI1: return propvariant.bVal;
           case VT_TYPE.VT_I2: return propvariant.iVal;
           case VT_TYPE.VT_UI2: return propvariant.uiVal;
           case VT_TYPE.VT_I4: return propvariant.lVal;
           case VT_TYPE.VT_UI4: return propvariant.ulVal;
           case VT_TYPE.VT_INT: return propvariant.intVal;
           case VT_TYPE.VT_UINT: return propvariant.uintVal;
           case VT_TYPE.VT_I8: return propvariant.hVal;
           case VT_TYPE.VT_UI8: return propvariant.uhVal;
           case VT_TYPE.VT_R4: return propvariant.fltVal;
           case VT_TYPE.VT_R8: return propvariant.dblVal;
           case VT_TYPE.VT_BOOL: return propvariant.boolVal;
           case VT_TYPE.VT_ERROR: return propvariant.scode;
           case VT_TYPE.VT_CY: return "Money";
           case VT_TYPE.VT_DATE: return propvariant.date;
           case VT_TYPE.VT_FILETIME: return propvariant.filetime;
           case VT_TYPE.VT_LPSTR: return Marshal.PtrToStringAnsi(propvariant.other);
           case VT_TYPE.VT_LPWSTR: return Marshal.PtrToStringUni(propvariant.other);
           default: return null;
         }
       }
    


    Change the PROPVARINAT enum to

    [StructLayout(LayoutKind.Explicit)]
     public struct PROPVARIANT
     {
       [FieldOffset(0)]
       public VT_TYPE vt;
       [FieldOffset(2)]
       public short wReserved1;
       [FieldOffset(4)]
       public short wReserved2;
       [FieldOffset(6)]
       public short wReserved3;
       [FieldOffset(8)]
       public sbyte cVal;
       [FieldOffset(8)]
       public byte bVal;
       [FieldOffset(8)]
       public short iVal;
       [FieldOffset(8)]
       public ushort uiVal;
       [FieldOffset(8)]
       public int lVal;
       [FieldOffset(8)]
       public uint ulVal;
       [FieldOffset(8)]
       public int intVal;
       [FieldOffset(8)]
       public uint uintVal;
       [FieldOffset(8)]
       public long hVal;
       [FieldOffset(8)]
       public ulong uhVal;
       [FieldOffset(8)]
       public float fltVal;
       [FieldOffset(8)]
       public double dblVal;
       /*[MarshalAs(UnmanagedType.Currency)]
       [FieldOffset(8)]
       public Decimal cyVal;*/
       [FieldOffset(8)]
       public DateTime date;
       [MarshalAs(UnmanagedType.VariantBool)]
       [FieldOffset(8)]
       public bool boolVal;
       [MarshalAs(UnmanagedType.Error)]
       [FieldOffset(8)]
       public int scode;
       [FieldOffset(8)]
       public FILETIME filetime;
       [FieldOffset(8)]
       public IntPtr other;
     }
    

    Thanks & Regards

    Ramakrishnan S

    Friday, July 1, 2011 2:12 PM
  • Hi,

    I need to do the same thing as you, get the properties of an Office document. I took the original link and built it. It gets the text of the document.

    I'm not that familar with C Sharp. However, I can't get it build with the additions you show. The solution doesn't have a PROPVARIANT enum so I added what you show to Ifilter.cs. When it compiles I get the error "Error 1 The type or namespace name 'VT_TYPE' could not be found (are you missing a using directive or an assembly reference?) D:\Downloads\Ifilter css\Source\EPocalipse.IFilter\IFilter.cs 38 16 EPocalipse.IFilter". I couldn't find it on a search and with the other additions, if that is not included PROPVARIANT is not defined. What am I mising?

    Can this be done in C++ with Visual Studio VC6 or VC2005?

    Thanks for your help.

    Don


    Don Rosengrant

    Monday, March 12, 2012 2:44 PM
  • Instead of VT_TYPE use VARTYPE.

    Friday, March 16, 2012 8:46 AM
  • I had tried that, but it didn't like that either.

    However, I solved the problem. I'm using the meta data handler based on the Microsoft sample dsofile.dll. To make it work on a 64 bit system, if MS Office 2007 is installed, it needs SP3, for MS Office 2010 it needs SP1.


    Don Rosengrant

    Friday, March 16, 2012 12:24 PM