是否可以为不在 shell 命名空间中的项目获取 shell 属性?

Is it possible to get shell properties for an item not in the shell namespace?

精简版

shell如何获取文件的属性?

长版

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

例如:

为了让 shell 读取这些属性,显然必须使用大量资源:

无论哪种方式,它都必须读取文件内容流并对文件内容做一些事情才能获得所有这些奇特的 shell 属性。换句话说:

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

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

我有不在 shell 命名空间中的项目;他们在数据存储中。我确实将它们暴露给 shell 到 IDataObject 作为 CF_FILEDESCRIPTORIStream 执行 copy-paste或 drag-drop。但除此之外,它们只是数据存储中的可流式 blob。

我希望能够利用才华横溢的 hard-working1 shell 团队所做的所有现有工作从 "file" 中读取元数据,最终仅作为 IStream.

存在

是否有一个绑定上下文选项可以让我得到一个基于IDataObject而不是IShellItem2的属性商店

所以而不是:

IPropertyStore ps = shellItem2.GetPropertyStore();

有没有:

IPropertyStore ps = GetShellPropertiesFromFileStream(stream);

?

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

奖金聊天 - IPropertyStoreFactory

This interface is typically obtained through IShellFolder::BindToObject or IShellItem::BindToHandler. It is useful for data source implementers who want to avoid the additional overhead of creating a property store through IShellItem2::GetPropertyStore. However, IShellItem2::GetPropertyStore is the recommended method to obtain a property store unless you are implementing a data source through a Shell folder extension.

尝试过

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

但是CLSID_PropertyStore不支持IInitializeWithStream

红利阅读

(在 属性 商店处理程序方面有一些经验)我如何看待解决方案:

  1. 为您的文件扩展名获取属性存储处理程序 CLSID。您应该使用 2 个注册键:

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

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

  4. 将它们组合成单个对象
  5. 查询 IInitializeWithStream (also you can try to query IPersistStream).

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