4

精简版

shell 如何获取文件的属性?

长版

Windows Shell 公开了关于shell 命名空间中项目(例如文件和文件夹)的丰富属性系统。

例如:

  • System.Title : SQL Server Native Client OLE DB 到 ODBC 转换的快速指南
  • System.Author : George Yan (KW)
  • System.Document.LastAuthor : rohanl
  • System.Comment : 要了解有关此演讲者的更多信息,查找其他 TEDTalks,并订阅此 Podcast 系列,请访问 www.TED.com 反馈:tedtalks@ted.com
  • System.ItemParticipants : George Yan (KW)
  • System.Company:Contoso _
  • System.Language:英语(美国)
  • System.Document.DateCreated : 6/‎10/‎2014 ‏‎5∶16∶30 ᴘᴍ
  • System.Image.Horizo​​ntalSize:1845 像素
  • System.Image.VerticalSize:4695 像素
  • System.Image.Horizo​​ntalResolution:71 dpi
  • System.Image.VerticalResolution:71 dpi

为了让 shell 读取这些属性,它显然必须使用很多来源:

  • Windows Media Foundation IMFMetadata非常适合图像和电影
  • Windows 映像组件 ( WIC ) 可能有很多用于读取元数据的 API
  • 我不确定是否可以从 Office 文档IFilter中检索TitleAuthorSubjectComments等

无论哪种方式,它都必须读取文件内容流并对文件的内容进行处理才能获得所有这些花哨的 shell 属性。换句话说:

IStream  \
   +      |--> [magic] --> IPropertyStore
 .ext    /

可以与我自己的流一起使用吗?

我有不在 shell 命名空间中的项目;它们在数据存储中。我确实将它们暴露给外壳,IDataObject就像CF_FILEDESCRIPTOR执行IStream复制粘贴或拖放一样。但除此之外,它们只是数据存储中的可流式 blob。

我希望能够利用非常有才华和勤奋的1 shell 团队所做的所有现有工作从“文件”中读取元数据,该文件最终仅作为IStream.

是否有一个绑定上下文选项可以让我获得基于 aIDataObject而不是 a的属性存储IShellItem2

所以而不是:

IPropertyStore ps = shellItem2.GetPropertyStore();

有没有:

IPropertyStore ps = GetShellPropertiesFromFileStream(stream);

?

shell 如何获取文件的所有属性?

奖金聊天 - IPropertyStoreFactory

此接口通常通过IShellFolder::BindToObjectIShellItem::BindToHandler 获得它对于希望避免通过IShellItem2::GetPropertyStore创建属性存储的额外开销的数据源实现者很有用。但是,除非您通过 Shell 文件夹扩展实现数据源,否则推荐使用IShellItem2::GetPropertyStore方法来获取属性存储。

试过了

IPropertyStore ps = CoCreateInstance(CLSID_PropertyStore);
IInitializeWithStream iws = ps.QueryInterface(IID_IInitializeWithStream);

CLSID_PropertyStore不支持IInitializeWithStream

奖金阅读

  • MSDN:初始化属性处理程序

    物业管理人员是物业系统的重要组成部分。它们由索引器在进程内调用以读取和索引属性值,并且还由 Windows 资源管理器在进程内调用以直接在文件中读取和写入属性值。

  • MSDN:注册和分发属性处理程序 (拼写注册表以获得乐趣并从另一端阅读合同)
4

1 回答 1

2

(在 Property Store 处理程序方面有一些经验)我如何看待解决方案:

  1. 获取文件扩展名的 PropertyStore 处理程序 CLSID。您应该使用 2 个 regkeys 密钥:

    • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers\.yourext
    • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\SystemPropertyHandlers
  2. 使用 CoCreateInstance 创建两个对象

  3. 如果您有 2 个对象,您可以使用PSCreateMultiplexPropertyStore将它们组合成单个对象

  4. 查询IInitializeWithStream(您也可以尝试查询IPersistStream)。

如果 PropertyStore 对象支持IInitializeWithStream / IPersistStream:你很幸运 - 只需初始化你的对象并查询你需要的属性。如果没有 - 您仍然有(脏)变体来创建临时文件,然后使用IPersistFile

于 2019-04-02T00:12:52.420 回答