属性处理程序最佳做法和常见问题解答

本主题介绍如何创建和注册属性处理程序以使用 Windows 属性系统。

本主题按如下所示进行组织:

最佳实践

重写文件系统属性

文件的某些属性由文件系统数据源提供,例如:

  • PKEY_FileName
  • PKEY_Extension
  • PKEY_ModifiedTime

通常,属性处理程序不能为这些属性提供值。 但是,在某些情况下,可以根据属性处理程序提供的注册信息重写这些属性。 属性处理程序用要重写的属性的名称填充 HKEY_CLASSES_ROOT\CLSID\{handler clsid}\OverrideFileSystemProperties。 这仅限于以下列表中所示的固定属性集,系统具有知识。

以下属性值支持重写:

有关所有 Shell 属性的完整列表,请参阅 Shell 属性

重要

仅当为文件编制索引时,才使用重写的属性值。 因此,从文件系统数据源浏览文件不会显示重写的值。  

以基于 XML 的文件格式存储属性

有两个基本选项可用于以基于 XML 的文件格式存储属性:

  • 根据文档的 XML 架构使用 XML 元素和属性Microsoft Store每个属性。 此方法更“XML 友好”。
  • 将整个属性存储序列化为内存二进制大型对象 (BLOB) ,将 BLOB 转换为 base64 编码的字符串,然后将该字符串存储在 XML 中。 这是这两种方法中更简单的方法,可用于轻松提供对开放元数据的支持。

例如,某些处理程序可能会合并这些方法,以标准 XML 格式存储一些重要值,并将其余值存储在 BLOB 中。

计算属性

某些属性派生自文件的特定属性。 例如, System.Image.Dimensions 属性由图像文件中图像的实际维度确定。 由于属性处理程序无法更改此类属性值,因此它们将被标记 isInnate="true" 在属性说明中。 其他属性通过特定属性的一部分或聚合多个属性的值来计算。 由于对这些“计算”属性的更新将产生模糊性,因此应如何更改“源”值,因此计算属性应标记为 isInnate="true" 属性说明或报告为只读。 后一个选项可通过指示处理程序从 IPropertyStoreCapabilities::IsPropertyWritable 返回S_FALSE。

常见问题

为什么我的属性处理程序不是由Windows搜索索引器加载?

Windows搜索索引器作为系统服务运行,无法加载存储在用户配置文件目录中的 DLL。 如果使用Microsoft Visual Studio进行生成和调试,它将 DLL 放置在用户配置文件 (中,因此索引器不会加载该 DLL) 。 若要解决此问题,请将配置文件文件夹外的 DLL 复制到 C :\Program Files\YourAppName) 并将其注册到其中 (。

有关开发用于Windows搜索索引器的属性处理程序的更具体指南,请参阅开发用于Windows搜索的属性处理程序

应通过“IPropertyStore::GetCount”和“IPropertyStore::GetAt”枚举方法发现哪些属性?

并非所有属性存储对象的客户端都使用这些方法。 某些客户端知道他们计划通过 PKEY 名称 () 直接请求的属性,或通过属性说明列表接收属性信息。 属性发现方法支持其他几个方案。 如果属性不需要参与这些方案,则无需枚举它。 因此,属性处理程序可以为未通过 IPropertyStore::GetCount 和 IPropertyStore::GetAt 方法发现的属性生成非VT_EMPTY值。

但是,如果满足以下任何条件,则应通过这些方法查看属性:

  • 如果属性已编制索引,以便其可搜索:这意味着它包含在Windows搜索属性存储中, (isColumn = "true"属性描述架构) 或可用于全文搜索 (inInvertedIndex = "true") 。 如果没有这些标志或缺少属性说明,类型为“string”的属性将自动添加到倒排索引以启用搜索。 由于 (属性系统中已安装属性说明) 的已知属性列表非常大, (超过 800 个属性) ,因此请求属性系统中注册的每个属性的每个属性处理程序是不切实际的。 相反,索引过程会枚举其索引的每个项的属性处理程序中的相关属性,并使用枚举属性的值来生成全文索引。
  • 如果当项的属性集重复时应复制该属性:若要实现“复制属性集”函数,源项使应通过 IPropertyStore::GetCount 和 IPropertyStore::GetAt 方法可见的属性。 不应包含不需要复制或不需要复制的属性。
  • 如果属性值不是空 (VT_EMPTY) : 为空的属性值不适用于客户端。 当客户端尝试返回空属性值时,将返回VT_EMPTY的值。 因此,不应枚举具有空值的属性。
  • 如果在调用“remove properties”函数时应删除该属性: 此功能存在以保护隐私;它通过枚举发现属性处理程序中的所有值,并删除用户选择的每个值以供删除。

注意

如果某个特定属性处理程序支持固定架构 (且不打开元数据) ,则枚举属性不会传达特定属性处理程序支持的属性集。 相反,此类处理程序应记录它们支持的属性集。

 

如何实现知道哪些文件格式支持打开元数据?

有关对打开元数据的支持的信息,请参阅文件类型中的“支持打开元数据的 文件类型”。

是否可以使用属性处理程序存储VT_NULL值?

否。 VT_NULL值将在调用 IPropertyStore::GetValue 和 IPropertyStore::SetValue 时转换为VT_EMPTY。

“PropVariantChangeType”函数支持哪些日期字符串格式?

通常,应使用VT_FILETIME来表示日期/时间值的属性。 但是,许多数据源以字符串形式提供此信息。 PropVariantChangeType 帮助程序 API 支持将某些字符串日期格式强制转换为 FILETIME 值,如下表所示。

格式 Windows Vista、Windows XP 和 Microsoft Windows 桌面搜索 (WDS) Windows 7 说明
yyyy/mm/dd:hh:mm:ss.uuu UTC;y=year、m=month、d=date、h=hours (24 小时时钟) 、m=minutes、s=seconds、u=microseconds
yyyy-mm-ddThh:mm:ssZ ISO8601 格式规范由“Z”时区指示器) 表示的 UTC (;y=year,m=month,d=date,h=hours (24 小时时钟) ,m=minutes,s=seconds;“T”是时间部分的分隔符。

是否可以创建只读属性处理程序?

是的。 某些属性处理程序实现不支持写入属性值。 这些属性处理程序应在对传递STGM_READWRITE的 IInitializeXXX::Initialize 的调用或对 IPropertyStore::SetValue 的任何调用时返回STGM_E_ACCESSDENIED。

在STGM_READ模式下打开的所有属性处理程序应在调用 IPropertyStore::SetValue 时返回STGM_E_ACCESSDENIED。

即使架构指示该属性是可写的,属性处理程序能否将属性视为只读的?

是。 在架构系统中,属性被注释为只读 (,包括具有 isInnate = "true") 或读/写的属性。 不支持编写架构应可写的特定属性的属性处理程序应实现 IPropertyStoreCapabilities,并在调用 IPropertyStoreCapabilities::IsPropertyWritable 时返回S_FALSE。 这表示在此处理程序和此文件的上下文中,该属性不可写入。

注意

无法执行反向操作。 不能使属性处理程序写入架构中标记为只读的属性