是否可以获取不在外壳名称空间中的项目的外壳属性?

时间:2019-04-01 20:26:13

标签: powershell winapi ipropertystorage

短版

shell如何获取文件的属性?

长版

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

例如:

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

要使外壳读取这些属性,显然它必须使用许多资源:

  • Windows Media Foundation IMFMetadata非常适合图像和电影
  • Windows Imaging组件( WIC )可能有很多用于读取元数据的API
  • 我不确定 IFilter 是否可以检索标题作者主题, Office文档中的评论

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

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

可以在我自己的视频流中使用它吗?

我有一些不在shell名称空间中的项目;它们在数据存储区中。当确实需要执行复制粘贴或拖放操作时,我确实通过CF_FILEDESCRIPTOR通过IDataObject1的形式将它们公开给了shell。但除此之外,它们只是数据存储中的可流blob。

我希望能够利用非常有才干且努力工作的所有现有工作 IPropertyStoreFactory Shell团队从“文件”中读取元数据,最后仅以IStream的形式存在。

也许有一个绑定上下文选项可以让我基于IStream而不是IDataObject 获取属性存储

因此,而不是:

IShellItem2

是否有一个

IPropertyStore ps = shellItem2.GetPropertyStore();

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

奖励聊天-IShellFolder::BindToObject

  

通常通过IShellItem::BindToHandlerIShellItem2::GetPropertyStore获得此接口。 它对于希望避免通过Initializing Property Handlers创建属性存储的额外开销的数据源实现者有用。但是,除非您通过Shell文件夹扩展名实现数据源,否则建议使用 IShellItem2 :: GetPropertyStore 获取属性存储。

尝试

IPropertyStore ps = GetShellPropertiesFromFileStream(stream);

但是IPropertyStore ps = CoCreateInstance(CLSID_PropertyStore); IInitializeWithStream iws = ps.QueryInterface(IID_IInitializeWithStream); 不支持CLSID_PropertyStore

奖金阅读

  • MSDN:Registering and Distributing Property Handlers
      

    属性处理程序是属性系统的关键部分。 索引器在过程中调用它们以读取和索引属性值,并且Windows资源管理器也在过程中调用它们以直接在文件中读取和写入属性值。

  • MSDN:this page (将注册表弄乱以获取乐趣,并从另一端读取合同)

1 个答案:

答案 0 :(得分:2)

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

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

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

  3. 如果您有2个对象,则可以使用 PSCreateMultiplexPropertyStore

  4. 将它们组合为单个对象
  5. 查询 IInitializeWithStream (也可以尝试查询 IPersistStream )。

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