Code:
/*
Code by TMouse.
Also see:
http://users.chello.be/ws36637/properties2.html
http://msdn.microsoft.com/library/en-us/stg/stg/writeread_sample.asp
*/
#include <objbase.h>
#include <stdio.h>
#if defined(_MSC_VER)
#pragma comment(lib, "ole32.lib")
#endif
// ================================================================================
HRESULT SetDocProperties(LPCWSTR szFile,
LONG cProps,
PROPSPEC* pPropSpecs,
PROPVARIANT* pPropVars)
{
HRESULT hr;
IPropertySetStorage* pStg = NULL;
IPropertyStorage* pPropStg = NULL;
// Open file. We could use StgCreateStorageEx() if we wanted to create the file.
hr = StgOpenStorageEx(szFile,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
STGFMT_ANY, 0, NULL, NULL,
IID_IPropertySetStorage, (void**) &pStg);
if (SUCCEEDED(hr))
{
// Now open the standard document properties...
hr = pStg->Open(FMTID_SummaryInformation,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &pPropStg);
// If the property set dosen't exist, we create it...
if (hr == STG_E_FILENOTFOUND)
{
hr = pStg->Create(FMTID_SummaryInformation, &FMTID_SummaryInformation,
PROPSETFLAG_DEFAULT,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, &pPropStg);
}
if (SUCCEEDED(hr))
{
// Write Properties...
hr = pPropStg->WriteMultiple(cProps, pPropSpecs, pPropVars, 100);
// Commit changes to file...
pPropStg->Commit(STGC_DEFAULT);
}
}
if (pStg) pStg->Release();
if (pPropStg) pPropStg->Release();
return hr;
}
// ================================================================================
HRESULT SetDocPropertyString(LPCWSTR szFile, PROPID propid, LPCWSTR szValue)
{
PROPSPEC PropSpec = { PRSPEC_PROPID, propid };
PROPVARIANT PropVariant = { 0 };
PropVariant.vt = VT_LPWSTR;
PropVariant.pwszVal = (LPWSTR) szValue;
return SetDocProperties(szFile, 1, &PropSpec, &PropVariant);
}
// ================================================================================
int main(void)
{
HANDLE hFile;
HRESULT hr;
PROPVARIANT PropVariants[3];
PROPSPEC PropSpecs[3];
CoInitialize(NULL);
// Create file to play with...
hFile = CreateFile("TEST.TXT", GENERIC_WRITE, FILE_SHARE_READ, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
CloseHandle(hFile);
// Set a single property...
hr = SetDocPropertyString(L"test.txt", PIDSI_COMMENTS, L"These are some comments.");
if (FAILED(hr)) printf("Failed to set property on test.txt. Is this drive NTFS?\n");
// Now set multiple properties at once...
PropSpecs[0].ulKind = PRSPEC_PROPID;
PropSpecs[0].propid = PIDSI_TITLE;
PropVariants[0].vt = VT_LPWSTR;
PropVariants[0].pwszVal = L"Document Summaries Sample";
PropSpecs[1].ulKind = PRSPEC_PROPID;
PropSpecs[1].propid = PIDSI_AUTHOR;
PropVariants[1].vt = VT_LPSTR;
PropVariants[1].pszVal = "TMouse";
PropSpecs[2].ulKind = PRSPEC_PROPID;
PropSpecs[2].propid = PIDSI_KEYWORDS;
PropVariants[2].vt = VT_LPWSTR;
PropVariants[2].pwszVal = L"Title, Subject, Author, Comments, Document Properties, COM, OLE";
hr = SetDocProperties(L"test.txt", 3, PropSpecs, PropVariants);
if (FAILED(hr)) printf("Failed to set properties on test.txt.\n");
// Set a property on a word doc (this file must already exist)...
hr = SetDocPropertyString(L"test.doc", PIDSI_SUBJECT, L"The wonders of...");
if (FAILED(hr)) printf("Failed to set property on test.doc. Does it exist?\n");
CoUninitialize();
printf("Press ENTER to continue...\n");
getchar();
return 0;
}