Click here to Skip to main content
Click here to Skip to main content
Go to top

Access the Summary Information Property Set of a file using Visual C++

, 9 Nov 2006
Rate this:
Please Sign up or sign in to vote.
How to access the Summary Information Property Set of a file, using Visual C++.

Introduction

This area of programming in Visual C++ is a little bit hidden. Many professionals want to know if it is possible to get and set the summary information of a file through Visual C++ (without using .NET), and if yes, then how?

When you right click a text file or any other file, you will find under Properties, a tab called 'Summary'. Inside this tab, there are many options like Title, Subject, Author, Keywords, and Comments. Yes, it is possible that you can change these entries from within your code in Visual C++.

In this article, I will explain the complete process and finally I will demonstrate this, to get and set the value of some property in the Summary tab of a file, using Visual C++ 6.0

The code

There is a function named StgOpenStorageEx available in Ole32.lib, and you can use this to open an existing root storage object in the file system. This function can be used to open compound files and regular files. To create a new file, use the StgCreateStorageEx function.

When you open a file, the system selects a structured storage implementation depending on which STGFMT flag you specify on the file type and on the type of drive where the file is stored.

When you call StgOpenStorageEx for an existing file, it will give you the pointer of IPropertySetStorage. The IPropertySetStorage interface creates, opens, deletes, and enumerates property set storages that support instances of the IPropertyStorage interface. For our current task, we should be familiar with the interface IPropertyStorage.

The IPropertyStorage interface manages a single property set in a property storage subobject; and the IPropertySetStorage interface manages the storage of groups of such property sets. Any file system entity can support IPropertySetStorage that is currently implemented in the COM compound file object.

The stand-alone implementation also provides the StgCreatePropStg and StgOpenPropStg helper functions, in addition to the Create and Open methods, to create and open property sets. These two functions add support the PROPSETFLAG_UNBUFFERED value so you can write changes directly to the property set instead of buffering them in a cache.

IPropertySetStorage::Create use property set Format Identifiers (FMTIDs) of the property which you are going to refer.

Below is the table of Predefined Property Set Format Identifiers which we can use according to our requirements:

Name Value Usage
FMTID_SummaryInformation {F29F85E0-4FF9-1068-AB91-08002B27B3D9} The Summary Information Property Set
FMTID_DocSummaryInformation {D5CDD502-2E9C-101B-9397-08002B2CF9AE} The DocumentSummaryInformation and UserDefined Property Sets
FMTID_UserDefinedProperties {D5CDD505-2E9C-101B-9397-08002B2CF9AE} The DocumentSummaryInformation and UserDefined Property Sets

These FMTIDs are defined in the UUID.LIB library file and the declaration is available in the OLE2.H header file.

According to our current task, we will use ‘FMTID_SummaryInformation’.

After create the property set successfully, we will use a structure ‘PROPSPEC’ to specify a property either by its property identifier (ID) or the associated string name.

The following table lists the string property names for the Summary Information property set, along with the respective property identifiers and variable type (VT) indicators. The names are not typically stored in the property set, but are inferred from the Property ID value. The Property ID String entries shown here correspond to the definitions found in the Win32 API header files.

Name Property ID string Property ID VT type
Title PIDSI_TITLE 0x00000002 VT_LPSTR
Subject PIDSI_SUBJECT 0x00000003 VT_LPSTR
Author PIDSI_AUTHOR 0x00000004 VT_LPSTR
Keywords PIDSI_KEYWORDS 0x00000005 VT_LPSTR
Comments PIDSI_COMMENTS 0x00000006 VT_LPSTR
Template PIDSI_TEMPLATE 0x00000007 VT_LPSTR
Last Saved By PIDSI_LASTAUTHOR 0x00000008 VT_LPSTR
Revision Number PIDSI_REVNUMBER 0x00000009 VT_LPSTR
Total Editing Time PIDSI_EDITTIME 0x0000000A VT_FILETIME (UTC)
Last Printed PIDSI_LASTPRINTED 0x0000000B VT_FILETIME (UTC)
Create Time/Date( (*)) PIDSI_CREATE_DTM 0x0000000C VT_FILETIME (UTC)
Last saved Time/Date( (*)) PIDSI_LASTSAVE_DTM 0x0000000D VT_FILETIME (UTC)

Number of Pages

Number of Words

Number of Characters

PIDSI_PAGECOUNT

PIDSI_WORDCOUNT

PIDSI_CHARCOUNT

0x0000000E

0x0000000F

0x00000010

VT_I4

VT_I4

VT_I4

Thumbnail PIDSI_THUMBNAIL 0x00000011 VT_CF
Name of Creating Application PIDSI_APPNAME 0x00000012 VT_LPSTR
Security PIDSI_SECURITY 0x00000013 VT_I4

* Some methods of file transfer, such as a download from a BBS, do not maintain the file system version of this information correctly.

Then, we will use another structure ‘PROPVARIANT’ for calling the ReadMultiple and WriteMultiple methods of IPropertyStorage to define the type tag and the value of a property in a property set.

So in this way, we can get and set properties in the summary tab under the Properties window of a file. Below is the complete code to accomplish this task.

Make a new project in Visual C++ 6.0 (type ‘Win32 Application’) named ‘SummaryPropPage’. Select ‘A simple Win32 application’ in the project creation step 1 and click OK. Now, copy the code below and paste it in your project’s .cpp file.

Before executing this code, make a file C:\Document.txt (because I use StgOpenStorageEx, you can use StgCreateStorageEx to create new one). Now, you are ready to execute the code.

In this code, I write and then read the ‘Title’ property under the Summary tab of the properties of a file named ‘Document’. You can use this code to get and set any property under the Summary tab, just change the property name (or you can use the property ID) in the PROPSPEC structure.

// SummaryPropPage.cpp : Defines the entry point
// for the application.
//

#include "stdafx.h"

#include <stdio.h>
#include <windows.h>
#include <ole2.h>


// Implicitly link ole32.dll
#pragma comment( lib, "ole32.lib" )



const FMTID PropSetfmtid ={
/* F29F85E0-4FF9-1068-AB91-08002B27B3D9 */
        0xf29f85e0,
        0x4ff9,
        0x1068,
        {0xab, 0x91, 0x08, 0x00, 0x2b, 0x27, 0xb3, 0xd9 }
        };



int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
     // TODO: Place code here.

    IPropertySetStorage *pPropSetStg = NULL;
    IPropertyStorage *pPropStg = NULL;
    PROPSPEC propspec; 
    PROPVARIANT propWrite; 
    PROPVARIANT propRead;
    HRESULT hr = S_OK;


    // Open a file and a property set within it.
    hr = StgOpenStorageEx( L"C:\\Document.txt",
                    STGM_DIRECT|STGM_SHARE_EXCLUSIVE|
                    STGM_READWRITE,
                    STGFMT_ANY,
                    // STGFMT_STORAGE //Structured 
                                      //Storage property sets
                    // STGFMT_FILE  //NTFS file system 
                                    //property sets
                    0,
                    NULL,
                    NULL,
                    IID_IPropertySetStorage,
                    reinterpret_cast<void**>(&pPropSetStg) );


    if( FAILED(hr) ) 
    throw L"Failed StgOpenStorageEx";

/*    
    hr = pPropSetStg->Open( PropSetfmtid, 
                            STGM_WRITE|
                            STGM_SHARE_EXCLUSIVE,
                            &pPropStg );
*/
    
    hr = pPropSetStg->Create( PropSetfmtid, NULL, 
                            PROPSETFLAG_DEFAULT,
                            STGM_CREATE|STGM_READWRITE|
                            STGM_SHARE_EXCLUSIVE,
                            &pPropStg );

    if( FAILED(hr) ) 
    throw L"Failed IPropertySetStorage::Open";


    //we can identify any property through its Name or its ID
//    propspec.ulKind = PRSPEC_LPWSTR;
//    propspec.lpwstr = L"Title";

    propspec.ulKind = PRSPEC_PROPID;
    propspec.propid  = 0x00000002;


    //specify the value of property
    propWrite.vt = VT_LPWSTR;
    propWrite.pwszVal = L"this value set through code";


    hr = pPropStg->WriteMultiple( 1, &propspec, 
         &propWrite, PID_FIRST_USABLE );

    if( FAILED(hr) ) 
    throw L"Failed IPropertyStorage::WriteMultiple";


    pPropStg->Release(); 
    pPropStg = NULL;


    //again open the property set

    hr = pPropSetStg->Open( PropSetfmtid, 
         STGM_READ|STGM_SHARE_EXCLUSIVE,
         &pPropStg );

    if( FAILED(hr) ) 
    throw L"Failed IPropertySetStorage::Open";


    // Read the property back and validate it
    hr = pPropStg->ReadMultiple( 1, &propspec, &propRead );
    if( FAILED(hr) ) 
    throw L"Failed IPropertyStorage::ReadMultiple";


    char* str = new char [wcslen(propRead.pwszVal) + 1];
    //    the "%S" will implicitly convert UNICODE to ANSI.
    wsprintfA ( str, "%S", propRead.pwszVal); 

    //if you want to display
    //    MessageBox(NULL,str,"Reading Value",MB_OK);

    if( hr == S_FALSE )
       throw L"Property didn't exist after " 
             L"reopening the property set"; 
    else if( propWrite.vt != propRead.vt )
       throw L"Property types didn't match " 
             L"after reopening the property set";
    else if( wcscmp( propWrite.pwszVal, propRead.pwszVal ) != 0 )
       throw L"Property values didn't match" 
             L" after reopening the property set";
    else
       wprintf( L"Success\n" );

    return 0;
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Najam ul Hassan
Software Developer (Senior)
United States United States
I have done Masters in Computer Sciences and for last seven years working in Visual C++ and C# on different domains.
Keep programming... . . .

Comments and Discussions

 
QuestionCannot get properties of MS Office 2013 .docx file PinmemberAllan Braun21-Jul-14 1:51 
Questionerror LNK2020: unresolved token (0A000015) IID_IPropertySetStorage PinmemberBhagya Wickramasinghe2-Mar-13 11:10 
QuestionIs it not possible to only read property ID and its value instead of Writing and then reading. PinmemberGouri2727-Aug-12 0:25 
Questionhow to add new options( i.e tile2, author 2 like that ) Summary Information Property Set of a file using Visual C++ Pinmemberchandrasekhar Dunna14-Mar-12 1:37 
Generalthanks a lot! simple and usefull code. Pinmemberalex d andrad12-Jan-11 3:49 
QuestionHow to access the properties using c# code? Pinmemberrdkcds15-Feb-10 2:42 
QuestionHelp,How can I modify the file's summary like bmp, gif, ico, jpg and png etc. picture format? Pinmemberolive20084-Jun-09 18:24 
QuestionUsing C++? PinmemberSathyanarayan B22-Sep-08 22:56 
QuestionHow to access the Summary Information Property Set of a file PinmemberPgmer24-Jul-08 0:33 
QuestionPropVariantClear or FreePropVariantArray PinmemberMember 430277114-Jul-08 4:00 
GeneralThanks!!! PinmemberMatin0318-Nov-07 20:33 
QuestionHow about ierarhical storages/substorages PinmemberSCHNELL DAN16-Aug-07 6:00 
QuestionHow about Set Title on MP3 files? PinmemberJohn62113-Jul-07 6:15 
Generalhelp Pinmemberakss_brr4-Jun-07 22:25 
GeneralRe: help PinmemberNajam ul Hassan5-Jun-07 7:39 
GeneralRe: help Pinmemberakss_brr6-Jun-07 4:41 
GeneralLost these info property set of a file Pinmembervietdoorgroup29-Mar-07 16:38 
Generaladvanced info Pinmemberdev2k34-Dec-06 14:17 
GeneralThank you very much Pinmembersudeep_ganga16-Nov-06 3:04 
Generalthank you very much for such a nice atricle Pinmemberpeter-00715-Nov-06 21:55 
GeneralThank you Pinmemberdigital_loser14-Nov-06 9:36 
QuestionMultiple properties ? Pinmemberpelekoydas13-Nov-06 22:02 
GeneralWorks for TXT files, but not DOC or WMV files PinmemberJCrane29-Nov-06 15:06 
GeneralRe: Works for TXT files, but not DOC or WMV files PinmemberPeter Cheeseman2-Feb-07 5:31 
GeneralRe: Works for TXT files, but not DOC or WMV files PinmemberGrober113-Apr-08 16:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 9 Nov 2006
Article Copyright 2006 by Najam ul Hassan
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid