获取office办公软件最后一次保存者值

  文件的详细信息如图

  获取office办公软件最后一次保存者值

  要取到这个信息,文件的的详细信息一般是是通过Shell32::Folder com技术取到的。代码如下:  

void EnumFileAttributes()
{
    wstring wszFolderPath = L"C:\\Users\\Administrator\\Desktop\\test";
    wstring wszFilePath = L"1234.doc";
    Shell32::IShellDispatchPtr pShellDispatch = NULL;
    Shell32::FolderPtr pFolder = NULL;
    Shell32::FolderItemPtr pItem = NULL;
    string sName;
    string sValue;

    do 
    {
        if(S_OK != pShellDispatch.CreateInstance(__uuidof(Shell32::Shell)))
        {
            break;
        }
            
        pFolder = pShellDispatch->NameSpace(wszFolderPath.c_str());
        if(NULL ==  pFolder)
        {
            break;
        }

         pItem = pFolder->ParseName(wszFilePath.c_str());
        if(NULL == pItem)
        {
            break;
        }
        
        for(int i = 0; i < 50; i++)
        {
            sName = pFolder->GetDetailsOf(0, i); 
            sValue = pFolder->GetDetailsOf((_variant_t((IDispatch*)pItem)), i);

            if(sName.empty() && sValue.empty())
            {
                break;
            }

            cout << "name:" << sName << "value:" << sValue << endl;
        }

    } while (false);

}

 记得调用前 CoInitialize(NULL);调用后使用 CoUninitialize();

   这段代码能够获取大多数文件的详细信息。但是对于办公软件,取不到最后一次保存者的值。

 以二进制打开文件,可以看到如下的图

获取office办公软件最后一次保存者值

可以看到这个文件的作者和最后一次保存着值基本挨着,但就是取不到最后一次保存着。为什么会这样呢。不知道。试了Shell32::Folder2的相关接口也取不到。

  经过多方搜索,找到文章  https://www.codeproject.com/Articles/16314/Access-the-Summary-Information-Property-Set-of-a-f?msg=4865283#xx4865283xx,

感觉这个文章挺靠谱的。遂下载了工程,尝试用 StgOpenStorageEx,IPropertyStorage 等API 获取最后一次保存者的值。

  经过一番尝试,发现能够获取。代码如下:  

 1 bool GetFileLastAuthor()
 2 {
 3     bool bReslt = false;
 4     IPropertySetStorage *pPropSetStg = NULL;
 5     IPropertyStorage *pPropStg = NULL;
 6     PROPSPEC propspec; 
 7     PROPVARIANT propRead;
 8 
 9     do 
10     {
11         if(FAILED(StgOpenStorageEx( L"C:\\Users\\Administrator\\Desktop\\test\\1234.doc",
12             STGM_READ|STGM_SHARE_EXCLUSIVE,
13             STGFMT_ANY,    NULL,NULL,NULL,
14             IID_IPropertySetStorage,
15             reinterpret_cast<void**>(&pPropSetStg)))) 
16         {
17             break;
18         }
19 
20         if(FAILED(pPropSetStg->Open(FMTID_SummaryInformation, STGM_READ|STGM_SHARE_EXCLUSIVE,&pPropStg))) 
21         {
22             break;
23         }
24 
25         propspec.ulKind = PRSPEC_PROPID;
26         propspec.propid  = PIDSI_LASTAUTHOR;
27         if(FAILED(pPropStg->ReadMultiple(1, &propspec, &propRead)))
28         {
29             break;
30         }
31         else
32         {
33             wprintf(L"%s",propRead.pwszVal);
34             bReslt = true;
35         }
36 
37     } while (false);
38 
39     if(pPropStg)
40     {
41         pPropStg->Release();
42     }
43 
44     if(pPropSetStg)
45     {
46         pPropSetStg->Release();
47     }
48 
49     return bReslt;
50 }

  API的使用自行msdn. 这里要说的有两点

    1 PIDSI_LASTAUTHOR 必须指定 FMTID_SummaryInformation。

    2 pPropStg->ReadMultiple 调用成功后,最后一次保存着的值不一定保存在propRead.pwszVal,也有可能在propRead.pszVal。这取决于propRead.vt类型。

  使用上述代码后,doc的文件最后一次保存者能取到,docx文件的取不到。

  显然doc 和 docx文件类型,数据组织差异很大。上述方法不适用docx xlsx pptx,那么docx的文件最后保存者怎么获取呢。

    docx是个压缩文件,可以先解压。解析出来的有一个docProps 的文件夹。在这个文件夹内,有个core.xml。测试的文件core.xml如下  

 1 <cp:coreProperties
 2     xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
 3     xmlns:dc="http://purl.org/dc/elements/1.1/"
 4     xmlns:dcterms="http://purl.org/dc/terms/"
 5     xmlns:dcmitype="http://purl.org/dc/dcmitype/"
 6     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 7     <dcterms:created xsi:type="dcterms:W3CDTF">2021-08-26T10:16:00Z</dcterms:created>
 8     <dc:creator>Windows 用户</dc:creator>
 9     <cp:lastModifiedBy>Administrator</cp:lastModifiedBy>
10     <dcterms:modified xsi:type="dcterms:W3CDTF">2021-08-26T10:26:57Z</dcterms:modified>
11     <cp:revision>3</cp:revision>
12 </cp:coreProperties>

  可以看到 cp:lastModifiedBy 的值是我所需要的。试过xlsx,pptx 都是如此。如有解压出来没有 docProps 文件夹的话,大概其真没有这些属性把。

参考

  https://blog.csdn.net/liangls1982/article/details/6233765

  

上一篇:如何清理Office 许可证文件?


下一篇:Excel 2016打开文档时提示“操作系统当前的配置不能运行此应用程序”