1

我一直在使用 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.&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 来获得相同的解决方案。

多谢!希望你能找到答案。

4

1 回答 1

1

该值在STAT_CHUNK's attribute字段中定义。它被定义为一个FULLPROPSPEC结构,它可以(大多数时候)与Windows Property System直接相关。

FULLPROPSPEC 可以指向 GUID+id 属性,也可以指向由其名称定义的自定义属性(理想情况下,您需要检查psProperty.ulKind以确定这一点)。今天,大多数实现只是不使用名称 thing 并坚持“属性”的 GUID(属性集)+ PROPID(int)定义。

因此,例如,这是一个示例代码,它能够确定使用PSGetNameFromPropertyKeyIPropertyDescription::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);
  }
}
于 2014-08-08T12:59:05.427 回答