使用过滤器c++获取OLE属性

get OLE properties using IFilter C++

本文关键字:OLE 属性 获取 c++ 过滤器      更新时间:2023-10-16

我一直在使用过滤器COM对象,以便从文件中提取文本。我已经设法提取了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.&nbsp;.&nbsp;.
        }
    }
    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 );
        }
    }
}

换句话说,我需要知道属性id是什么,并将其与属性的值相匹配。

我已经看到了使用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);
  }
}