如何使用StgOpenStorageEx函数提取.docx,.xlsx,.pptx的文档属性?

问题描述

我正在使用 StgOpenStorageEx ()获取文档属性,例如标题主题标签,作者等。

我已成功获取.doc,.xls,.ppt文件的所有这些属性。但没有为 .docx,.xlsx,.pptx

获得任何东西

StgOpenStorageEx()已成功打开.docx文件,但未获取任何属性。为什么?

我想念什么吗?

代码

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

// Dumps simple PROPVARIANT values.
void DumpPropVariant(PROPVARIANT* pPropVar) {
    // Don't iterate arrays,just inform as an array.
    if (pPropVar->vt & VT_ARRAY) {
        printf("(Array)\n");
        return;
    }
    // Don't handle byref for simplicity,just inform byref.
    if (pPropVar->vt & VT_BYREF) {
        printf("(ByRef)\n");
        return;
    }

    // Switch types.
    switch (pPropVar->vt) {
    case VT_EMPTY:
        printf("(VT_EMPTY)\n");
        break;
    case VT_NULL:
        printf("(VT_NULL)\n");
        break;
    case VT_BLOB:
        printf("(VT_BLOB)\n");
        break;
    case VT_BOOL:
        printf("%s (VT_BOOL)\n",pPropVar->boolVal ? "TRUE/YES" : "FALSE/NO");
        break;
    case VT_I2: // 2-byte signed int.
        printf("%d (VT_I2)\n",(int)pPropVar->iVal);
        break;
    case VT_I4: // 4-byte signed int.
        printf("%d (VT_I4)\n",(int)pPropVar->lVal);
        break;
    case VT_R4: // 4-byte real.
        printf("%.2lf (VT_R4)\n",(double)pPropVar->fltVal);
        break;
    case VT_R8: // 8-byte real.
        printf("%.2lf (VT_R8)\n",(double)pPropVar->dblVal);
        break;
    case VT_BSTR: // OLE Automation string.
    {
        // Translate into ASCII.
        char dbcs[1024];
        char* pbstr = (char*)pPropVar->bstrVal;
        int i = wcstombs(
            dbcs,pPropVar->bstrVal,*((DWORD*)(pbstr - 4)));
        dbcs[i] = 0;
        printf("%s (VT_BSTR)\n",dbcs);
    }
    break;
    case VT_LPSTR: // Null-terminated string.
    {
        printf("%s (VT_LPSTR)\n",pPropVar->pszVal);
    }
    break;
    case VT_FILETIME:
    {
        const char* dayPre[] =
        { "Sun","Mon","Tue","Wed","Thu","Fri","Sat" };

        FILETIME lft;
        FileTimetoLocalFileTime(&pPropVar->filetime,&lft);
        SYstemTIME lst;
        FileTimetoSystemTime(&lft,&lst);

        printf("%02d:%02d.%02d %s,%s %02d/%02d/%d (VT_FILETIME)\n",1 + (lst.wHour - 1) % 12,lst.wMinute,lst.wSecond,(lst.wHour >= 12) ? "pm" : "am",dayPre[lst.wDayOfWeek % 7],lst.wMonth,lst.wDay,lst.wYear);
    }
    break;
    case VT_CF: // Clipboard format.
        printf("(Clipboard format)\n");

        break;
    default: // Unhandled type,consult wtypes.h's VARENUM structure.
        printf("(Unhandled type: 0x%08lx)\n",pPropVar->vt);
        break;
    }
}

// Dump's built-in properties of a property storage.
void DumpBuiltInProps(IPropertySetStorage* pPropSetStg) {
    printf("\n==================================================\n");
    printf("BuiltInProperties Properties...\n");
    printf("==================================================\n");

    IPropertyStorage* pPropStg = NULL;
    HRESULT hr;

    // Open summary information,getting an IpropertyStorage.
    hr = pPropSetStg->Open(FMTID_Summaryinformation,STGM_READ | STGM_SHARE_EXCLUSIVE,&pPropStg);
    //hr = pPropSetStg->Open(FMTID_UserDefinedProperties,//STGM_READ | STGM_SHARE_EXCLUSIVE,&pPropStg);
    if (Failed(hr)) {
        printf("No Summary-information.\n");
        return;
    }
    // Array of PIDSI's you are interested in.
    struct pidsiStruct {
        const char* name;
        long pidsi;
    } pidsiArr[] = {
       {"Title",PIDSI_TITLE},// VT_LPSTR
       {"Subject",PIDSI_SUBJECT},// ...
       {"Author",PIDSI_AUTHOR},{"Keywords",PIDSI_KEYWORDS},{"Comments",PIDSI_COMMENTS},{"Template",PIDSI_TEMPLATE},{"LastAuthor",PIDSI_LASTAUTHOR},{"Revision Number",PIDSI_REVNUMBER},{"Edit Time",PIDSI_EDITTIME},// VT_FILENAME (UTC)
       {"Last printed",PIDSI_LASTPRINTED},// ...
       {"Created",PIDSI_CREATE_DTM},{"Last Saved",PIDSI_LASTSAVE_DTM},{"Page Count",PIDSI_PAGECOUNT},// VT_I4
       {"Word Count",PIDSI_WORDCOUNT},// ...
       {"Char Count",PIDSI_CHARCOUNT},{"Thumpnail",PIDSI_THUMBNAIL},// VT_CF
       {"AppName",PIDSI_APPNAME},// VT_LPSTR
       {"Doc Security",PIDSI_DOC_Security},// VT_I4
       {0,0}
    };
    // Count elements in pidsiArr.
    int nPidsi = 0;
    for (nPidsi = 0; pidsiArr[nPidsi].name; nPidsi++);

    // Initialize PROPSPEC for the properties you want.
    PROPSPEC* pPropSpec = new PROPSPEC[nPidsi];
    PROPVARIANT* pPropVar = new PROPVARIANT[nPidsi];

    for (int i = 0; i < nPidsi; i++) {
        ZeroMemory(&pPropSpec[i],sizeof(PROPSPEC));
        pPropSpec[i].ulKind = PRSPEC_PROPID;
        pPropSpec[i].propid = pidsiArr[i].pidsi;
    }

    // Read properties.
    hr = pPropStg->ReadMultiple(nPidsi,pPropSpec,pPropVar);

    if (Failed(hr)) {
        printf("IPropertyStg::ReadMultiple() Failed w/error %08lx\n",hr);
    }
    else {
        // Dump properties.
        for (int i = 0; i < nPidsi; i++) {
            printf("%16s: ",pidsiArr[i].name);
            DumpPropVariant(pPropVar + i);
        }
    }

    // De-allocate memory.
    delete[] pPropVar;
    delete[] pPropSpec;

    // Release obtained interface.
    pPropStg->Release();

}

// Dump's custom and built-in properties of a compound document.
void DumpProps(char* filename) {
    // Translate filename to Unicode.
    WCHAR wcFilename[1024];
    int i = mbstowcs(wcFilename,filename,strlen(filename));
    wcFilename[i] = 0;

    IStorage* pStorage = NULL;
    IPropertySetStorage* pPropSetStg = NULL;
    HRESULT hr;

    hr = StgOpenStorageEx(wcFilename,0x00400000L | STGM_READ | STGM_SHARE_DENY_NONE,// Here: 0x00400000L = STGM_DIRECT_SWMR (Direct Single Writer Multiple Reader)
        STGFMT_ANY,// STGFMT_STORAGE //Structured Storage property sets
        // STGFMT_FILE  //NTFS file system property sets
        NULL,NULL,IID_IPropertySetStorage,//IID_IPropertySetStorage,IID_IStorage
        reinterpret_cast<void**>(&pPropSetStg));

    if (Failed(hr)) {
        if (hr == STG_E_FILENOTFOUND)
            printf("File not found.");
        else if (hr == STG_E_FILEALREADYEXISTS)
            printf("Not a compound file. ERROR: %08lx",hr);
        else
            printf("StgOpenStorage() Failed w/error %08lx",hr);
        return;
    }

    // Dump properties.
    DumpBuiltInProps(pPropSetStg);

    // Release obtained interfaces.
    if(pPropSetStg)
        pPropSetStg->Release();

}

// Program entry-point.
void main(int argc,char** argv) {

    char filePath[] = "C://word1.docx"; // file
  
    // Pass filename to the subroutine.
    DumpProps(filePath);
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)