开发 IFilter 加载项

注意

Windows 桌面搜索 2.x 是一项过时的技术,最初作为 Windows XP 和 Windows Server 2003 的加载项提供。 在更高版本中,请改用 Windows 搜索

可以使用筛选器加载项(实现 IFilter接口的组件)扩展 Microsoft Windows 桌面搜索 (WDS) ,以包括新的文件类型。 筛选器负责访问和分析文件中的数据,并返回属性和值对以及用于索引的文本块。 在索引编制过程中,WDS 使用每个文件或项的 URL 调用相应的筛选器。 筛选器首先提取与 WDS 架构中标记为可检索的属性对应的元数据,例如标题、文件大小和上次修改日期。 然后,它将项内容拆分为文本块。 WDS 将筛选器返回的属性和文本添加到目录。 WDS 可以为已注册筛选器的任何文件类型编制索引。

在某些情况下,无需编写新筛选器。 WDS 2.x 包含超过 200 种类型的项目的筛选器, (包括纯文本项(如 HTML、XML 和源代码文件),) 并使用与 SharePoint Services 相同的 IFilter技术。 如果已经为文件类型安装了筛选器,WDS 可以使用这些现有筛选器为这些数据编制索引。 此外,WDS 还包括基于纯文本的文件类型的常规筛选器。 如果你有可由现有 SharePoint Services 筛选器或纯文本筛选器处理的文件类型,则可以将文件扩展名和筛选器 GUID 添加到注册表,以便 WDS 可以找到并使用它 (请参阅 注册筛选器加载项 ,了解) 的详细信息。

但是,如果你有非纯文本和专有数据或文件格式,编写自定义筛选器实现是确保 WDS 可以在目录中为文件格式编制索引的唯一方法。 一个文件类型只能有一个筛选器加载项,因此可以替代现有筛选器或让另一个筛选器替代特定文件类型的筛选器。

本节包含下列主题:

必需的筛选器接口

筛选器外接程序必须实现 IFilter接口和以下接口之一:

  • IPersistStream - 从流加载数据。 这比使用文件更安全,因为不会将任何内容写入磁盘。 IPersistStream 接口是与 Windows Vista 向前兼容的首选方法。
  • IPersistFile 接口 - 从文件加载数据。 Windows Vista 不支持此接口。
  • IPersistStorage 接口 - 从 OLE COM 结构化存储加载数据。

筛选器外接程序使用这些接口获取项的内容,并迭代返回索引,直到到达文件末尾。 筛选器加载项应尽可能可靠,以处理损坏的文件以及不符合预期输入格式的文件。

IFilter 接口

这是筛选器实现所需的接口。 有关详细信息,请参阅 IFilter接口参考。

方法 说明
Init() 初始化筛选会话。
GetChunk () 将筛选器置于第一个或下一个区块的开头,并返回描述符。
GetText () 从当前区块中检索文本。
GetValue() 从当前区块中检索属性值。
BindRegion () 目前保留供内部使用;不实现。 此方法返回E_NOTIMPL。

 

IPersistStream

此接口从流加载文件,以便比 IPersistFile 接口 更安全地处理 ,因为运行 IPersistStream 筛选器的上下文不需要在磁盘上或通过网络打开任何文件的权限。 在用于访问单个文件的两种方法中,这是与 Windows 向前兼容的首选方法。

方法 说明
IsDirty () 检查是否有更改。 此方法在筛选器中返回E_NOTIMPL。
InitNew () 创建新存储。 此方法在筛选器中返回E_NOTIMPL。
Load () 从以前保存对象的流中初始化对象。
Save () 将对象保存到指定的流中,并指示对象是否应重置其脏标志。 此方法在筛选器中返回E_NOTIMPL。
GetSizeMax () 返回保存该对象所需的流的大小(以字节为单位)。 此方法在筛选器中返回E_NOTIMPL。

 

IPersistFile

此接口按绝对路径加载文件,在 Windows Vista 中不受支持。

方法 说明
GetCurFile () 获取与 对象关联的文件的当前名称。 返回 Load () 中指定的路径。
Load () 打开指定文件并从文件内容初始化对象。 可以延迟打开文件,直到需要它。
GetClassID () 返回新文件类型 (CLSID) 的类标识符。 应使用 uuidgen.exe 生成唯一的 CLSID。
IsDirty () 只需在筛选器中返回E_NOTIMPL
Save () 只需在筛选器中返回E_NOTIMPL
SaveCompleted () 只需在筛选器中返回E_NOTIMPL

 

IPersistStorage

此接口支持结构化存储模型,其中每个包含的对象都有自己的存储,该存储嵌套在容器的存储中。 与 IPersistFile 接口一样,此接口按绝对路径加载,在 Windows Vista 中不受支持。

方法 说明
IsDirty () 检查是否有更改。 此方法返回筛选器中的E_NOTIMPL。
InitNew () 创建新存储。 此方法返回筛选器中的E_NOTIMPL。
Load () 保存存储。 此方法返回筛选器中的E_NOTIMPL。
Save () 返回保存该对象所需的流的大小(以字节为单位)。 此方法返回筛选器中的E_NOTIMPL。
SaveCompleted () 保留以供内部使用。 此方法返回筛选器中的E_NOTIMPL。
HandsOffStorage () 保留以供内部使用。 此方法返回筛选器中的E_NOTIMPL。

 

输出带筛选器的属性

筛选器的目的是提取文件的内容和属性,以包含在全文索引中。 WDS 首先在 IPersistFile、IPersistStream 或 IPersistStorage 实现上调用 Load 方法,然后调用 IFilter 实现的 Init 方法。 调用 GetChunk 以检索文本区块或属性值数据,然后根据需要多次调用 GetTextGetValue,以检索与区块关联的所有文本或属性值。 此过程将重复,直到 GetChunk 报告文档中没有更多区块。

GetChunk 方法从要筛选的文件中检索有关第一个或下一个逻辑信息块的信息,并在STAT_CHUNK结构中返回该信息,包括单调增加的区块 ID、有关当前区块与上一个区块的关系的状态信息、指示区块是包含文本还是值的标志, 区块的区域设置和区块的属性规范。 属性规范是由 CLSID 和整数或字符串属性标识符组成的 FULLPROPSPEC , (例如 D5CDD505-2E9C-101B-9397-08002B2CF9AE/PerceivedType) 。 它标识属性的类型,而不是属性值本身。

区块区域设置标识符用于选择适当的断字符,正确标识它非常重要。 如果筛选器无法确定文本的区域设置,则应采用默认的系统区域设置,可通过 GetSystemDefaultLCID 使用。 如果控制文件格式,并且它当前不包含区域设置信息,则应添加用户功能以启用正确的区域设置标识。 使用不匹配的断字符可能会导致用户的查询体验不佳。

GetChunk 仅管理访问区块,不返回文本或属性值本身。 相反,对 GetTextGetValue 的后续调用会检索区块的正文。 GetText 从当前CHUNK_TEXT块返回文本区块,即 Unicode 字符串。 如果当前区块太大,可能需要多次调用 GetText 方法。 每次调用 GetText 方法时,都会从最后一次调用 GetText 方法时检索紧跟在文本后面的文本。 例如,一个调用中的最后一个字符可以位于单词中间,下一个调用中的第一个字符将继续该单词。 搜索引擎必须处理这种情况。

GetValue 返回 PROPVARIANT 结构中当前CHUNK_VALUE区块的属性值,这些区块可以保存各种数据类型。 GetValue 必须使用 CoTaskMemAlloc 分配 PROPVARIANT 结构本身。 GetValue 的调用方负责使用 PropVariantClear 释放 PROPVARIANT 指向的内存,并使用 CoTaskMemFree 释放结构本身。 有关 PROPVARIANTs 的详细信息,请参阅 PROPVARIANT 参考。

属性值

筛选器至少应输出以下属性,这些属性是 WDS 结果视图中的默认列。

GUID PROPSPEC 友好名称 说明
F29F85E0-4FF9-1068-AB91-08002B27B3D9 2 PrimaryTitle 为此项显示的标题。
F29F85E0-4FF9-1068-AB91-08002B27B3D9 4 PrimaryAuthors 与此项最相关的人员。
D5CDD505-2E9C-101B-9397-08002B2CF9AE PrimaryDate PrimaryDate 项目最重要的日期,如电子邮件接收日期或文件修改日期。
D5CDD505-2E9C-101B-9397-08002B2CF9AE PerceivedType PerceivedType 正在分析的文件的类型。 必须与 WDS 感知类型中列出的 Windows 桌面搜索 类型之一匹配。

 

对于纯文本项,WDS 会将所有文本和系统定义的属性(如文件大小或扩展名)提取到索引) 。 可返回到索引的其他类型的属性包括:

  • 对于文件:作者、标题、状态、关键字
  • 对于媒体:专辑、流派、相机制作、拍摄日期
  • 对于通信:发件人、收件人、抄送、重要性
  • 对于联系人:职务、业务电话、公司

上面的列表对指定感知类型共有的属性进行分组;但是,无论类型如何,都可以使用任何属性。 例如,company 可用于联系人的雇主姓名,也可用于引用与该文件相关的客户的名称。 其中许多属性用于在 WDS 结果视图中显示搜索结果。 例如,文件的 Title 属性在默认结果视图中显示为main列。 IFilter 对象应输出与其正在分析的项类型相关的所有属性。 无法在 WDS 2.x 中添加自定义属性。 有关可用属性的完整列表,请参阅 WDS 架构

筛选器加载项安装

安装筛选器涉及将 DLL 复制到 Program Files 目录中的相应位置并对其进行注册。 筛选器应为安装实现自注册,并应遵循以下准则:

  • 安装程序必须使用 EXE 或 MSI 安装程序。
  • 必须提供发行说明。
  • 必须为安装的每个加载项创建“ 添加/删除程序” 条目。
  • 安装程序必须接管当前外接程序所理解的特定文件类型或存储的所有注册表设置。
  • 如果覆盖以前的加载项,安装程序应通知用户。
  • 如果较新的外接程序覆盖了以前的外接程序,则应能够还原上一个外接程序的功能,并使其成为该文件类型的默认外接程序或再次存储。

注册所需的 CLSD

每个筛选器都有三个类标识符或 CLSID 关联。 您需要生成其中一个或多个 (使用uuidgen.exe) 注册筛选器外接程序。

  • 第一个标识所有筛选器的持久性处理程序IID_IFilter,即 {89BCB740-6119-101A-BCB7-00DD010655AF}。 对于实现 IFilter 的所有筛选器,此 CLSID 是常量。
  • 第二个 (IID_IFilter键的值) 标识文件类型的 IFilter 实现。 此键包含一个 InprocServer32 值,该值按路径和线程模型指定 DLL 名称。 如果筛选器位于系统路径(如 system32 目录)中,则文件名就足够了。 否则,此值应具有完整的路径规范。
  • 第三个标识筛选器处理的文件类型,由 IPersist 接口上的 GetClassID 方法返回。

注意

在 Microsoft 操作系统的未来版本中,在 system32 目录中安装文件可能会变得更加困难,因此我们建议在“程序文件”下安装这些文件,并在注册表中包含筛选器的完整路径。 出于安全原因,在注册表中指定 DLL 的完整路径也是谨慎的做法。 否则,如果 DLL 的“特洛伊木马”版本恰好位于版本之前的进程路径中,则可能会加载该 DLL 版本。

 

注册模型

当 WDS 准备好筛选文件时,它会在文件的扩展名下的注册表中查找以确定要加载的筛选器。 然后,它遵循一系列注册表链接,按以下顺序查找筛选器 DLL 的名称:

  1. 从位于:

    HKEY_CURRENT_USER\SOFTWARE\Microsoft\RSSearch\ContentIndexCommon\Filters\Override\RSApp

    HKEY_CURRENT_USER\SOFTWARE\Microsoft\RSSearch\ContentIndexCommon\Filters

  2. 从以下位置的文件内容类型:

    HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MIME\Database\Content Type

  3. 从文件扩展名 (与 Win32 LoadIFilter API) 相同的位置:

    HKEY_CURRENT_USER\SOFTWARE\Microsoft\RSSearch\ContentIndexCommon\Filters\Override\RSApp

    HKEY_CURRENT_USER\SOFTWARE\Microsoft\RSSearch\ContentIndexCommon\Filters

    HKEY_CLASSES_ROOT\extpersistentHandler-CLSID-IID_IFilter-CLSID>>>

  4. 从默认位置:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\RSSearch\ContentIndexCommon\Filters

注册筛选器外接程序

需要在注册表中总共创建 8 个条目才能注册筛选器加载项,其中:

  • .ext 是新的文件扩展名
  • GUID_1 可以是为此扩展生成的任何新 GUID
  • 89BCB740-6119-101A-BCB7-00DD010655AF 是 IFilter 接口 GUID,它是所有 IFilter 实现的常量。
  1. 使用以下键和值注册文件扩展名的永久性处理程序:

    HKEY_CLASSES_ROOT\<.ext>\PersistentHandler
       (Default) = {GUID_1}
    
    HKEY_CLASSES_ROOT\CLSID\{GUID_1}
       (Default) = <Persistent Handler Description>
    
    HKEY_CLASSES_ROOT\CLSID\{GUID_1}\PersistentAddinsRegistered
       (Default) = (Value Not Set)
    
    HKEY_CLASSES_ROOT\CLSID\{GUID_1}\PersistentAddinsRegistered\{89BCB740-6119-101A-BCB7-00DD010655AF}
       (Default) = {CLSID of IFilter implementation}
    
    HKEY_CLASSES_ROOT\CLSID\{GUID_1}\PersistentHandler
       (Default) = {GUID_1}
    
  2. 使用以下键和值注册 IFilter 实现:

    HKEY_CLASSES_ROOT\CLSID\{CLSID of IFilter implementation}
       (Default) = Extension IFilter Description">
    
    HKEY_CLASSES_ROOT\CLSID\{CLSID of IFilter implementation}\InprocServer32
       (Default) = <DLL Install Path>
       ThreadingModel = Both
    
  3. 使用以下键和值向 Windows 桌面搜索注册 IFilter 实现:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\RSSearch\ContentIndexCommon\Filters\Extension\<.ext>
       (Default) = {CLSID of IFilter implementation}"
    

参考

SchemaTable

感知类型

开发协议处理程序

其他资源

IFilter