Я использовал IFilter COM Object для извлечения текста из файлов.
Мне удалось извлечь свойства OLE ценности (например, ценность автора, ценность компании и т. д.), но я не мог понять, как узнать, какой ценностью является автор, компания и т. д.
CoInitialize(NULL);
IFilter *pFilt;
HRESULT hr = LoadIFilter( L"c:\\bla.docx", 0, (void**)&pFilt );
if ( FAILED( hr ) )
{
cout<<"Bla"<<endl;
}
ULONG flags;
hr = pFilt->Init( IFILTER_INIT_APPLY_INDEX_ATTRIBUTES, 0, 0, &flags );
if ( FAILED( hr ) )
{
cout<<"Bla"<<endl;
}
if(flags == 1)
{
cout<<"With OLE!"<<endl;
}
STAT_CHUNK chunk;
while ( SUCCEEDED( hr = pFilt->GetChunk( &chunk ) ) )
{
if ( CHUNK_TEXT == chunk.flags )
{
WCHAR awc[100];
ULONG cwc = 100;
while ( SUCCEEDED( hr = pFilt->GetText( &cwc, awc ) ) )
{
cout<<awc<<endl;
// process the text buffer. . .
}
}
else // CHUNK_VALUE
{
PROPVARIANT *pVar;
while ( SUCCEEDED( hr = pFilt->GetValue( &pVar ) ) )
{
**// Right here, i can see the value of pVar is the correct author, but i dont know how to tell this is the author, or the company etc..**
PropVariantClear( pVar );
CoTaskMemFree( pVar );
}
}
}
Другими словами, мне нужно знать, что такое идентификатор свойства, и сопоставить его со значением свойства.
Я видел решения, использующие IPropertyStorage-> ReadMultiple, но я пытаюсь получить то же самое с помощью IFilter.
Большое спасибо!
Надеюсь, вы найдете ответ.
Значение определяется в STAT_CHUNK's
attribute
поле. Это определить как FULLPROPSPEC
структура, которая может быть (в большинстве случаев) напрямую связана с Система свойств Windows.
FULLPROPSPEC может указывать либо на свойство GUID + id, либо на пользовательское свойство, определяемое его именем (в идеале вам необходимо проверить psProperty.ulKind
определить это). Сегодня большинство реализаций просто не используют имя вещи и придерживаются определения GUID (набор свойств) + PROPID (int) «свойства».
Так, например, это пример кода, который способен определить, какое имя свойства и значение отформатированы в виде строки, используя PSGetNameFromPropertyKey а также IPropertyDescription :: FormatForDisplay :
...
if (CHUNK_VALUE == chunk.flags)
{
if (chunk.attribute.psProperty.ulKind == PRSPEC_PROPID)
{
// build a Windows Property System property key
// need propsys.h & propsys.lib
PROPERTYKEY pk;
pk.fmtid = chunk.attribute.guidPropSet;
pk.pid = chunk.attribute.psProperty.propid;
PWSTR name;
if (SUCCEEDED(PSGetNameFromPropertyKey(pk, &name)))
{
wprintf(L" name:'%s'\n", name);
CoTaskMemFree(name);
}
IPropertyDescription *pd;
if (SUCCEEDED(PSGetPropertyDescription(pk, IID_PPV_ARGS(&pd))))
{
PROPVARIANT *pVar;
hr = pFilt->GetValue(&pVar);
if (SUCCEEDED(hr))
{
LPWSTR display;
if (SUCCEEDED(pd->FormatForDisplay(*pVar, PDFF_DEFAULT, &display)))
{
wprintf(L" value:'%s'\n", display);
CoTaskMemFree(display);
}
PropVariantClear(pVar);
}
pd->Release();
}
continue;
} // otherwise it's a string
PROPVARIANT *pVar;
hr = pFilt->GetValue(&pVar);
if (SUCCEEDED(hr))
{
// do something with the value
PropVariantClear(pVar);
}
}