文件的详细信息如图
要取到这个信息,文件的的详细信息一般是是通过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();
这段代码能够获取大多数文件的详细信息。但是对于办公软件,取不到最后一次保存者的值。
以二进制打开文件,可以看到如下的图
可以看到这个文件的作者和最后一次保存着值基本挨着,但就是取不到最后一次保存着。为什么会这样呢。不知道。试了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