筛选器处理程序( IFilter 接口的实现)扫描文档以获取文本和属性。 筛选器处理程序从这些项中提取文本块,筛选掉嵌入格式并保留有关文本位置的信息。 它们还会提取值片段,这些片段是文档属性。 IFilter 是构建更高级别应用程序的基础,例如文档索引器和独立于应用程序的查看器。
本主题按如下所示进行组织:
关于 IFilter 接口
Microsoft Windows 搜索使用筛选器提取项目内容,以便将其包含在全文索引中。 通过编写筛选器以提取内容,并编写属性处理程序以提取文件属性,从而扩展 Windows 搜索功能,使其能够为新文件类型或专有文件类型编制索引。
IFilter 接口旨在满足全文搜索引擎的特定需求。 全文搜索引擎(如 Windows 搜索)调用 IFilter 方法来提取文本和属性信息并将其添加到索引。 Windows 搜索将返回的 IFilter::GetText 方法的结果分解为单词、规范化它们,并将其保存在索引中。 如果可用,搜索引擎使用文本区块的语言代码标识符(LCID)来执行特定于语言的断字和规范化。
Windows 搜索使用下表中所述的三个函数来访问已注册的筛选器处理程序( IFilter 接口的实现)。 加载和绑定到嵌入对象的筛选器处理程序时,这些函数特别有用。
| 功能 | Description |
|---|---|
| LoadIFilter | 获取指向最适合指定内容类型的 IFilter 的指针。 |
| BindIFilterFromStorage | 获取指向最适合 IStorage Interface 对象中包含的内容的 IFilter 的指针。 |
| BindIFilterFromStream | 获取指向IFilter的指针,该IFilter最适合用于从流变量中检索指定类标识符 (CLSID)。 |
IFilter 接口有五种方法,如下表所述。
| 方法 | Description |
|---|---|
| IFilter::Init | 初始化筛选会话。 |
| IFilter::GetChunk | 将 IFilter 定位在第一个或下一个区块的开头,并返回描述符。 |
| IFilter::GetText | 从当前区块中检索文本。 |
| IFilter::GetValue | 从当前区块中检索值。 |
| IFilter::BindRegion | 检索表示指定对象部分的接口。 保留以供将来使用。 |
隔离过程
Windows 搜索使用受限权限在本地系统安全上下文中运行 IFilters。 在此 IFilter 主机隔离过程中,将删除多个权限:
- 受限代码
- 所有人
- Local
- 交互
- 经过身份验证的用户
- 内置用户
- 用户的安全标识符(SID)
删除这些权限意味着 IFilter 接口无权访问磁盘系统或网络或任何用户界面或剪贴板功能。 此外,隔离进程在阻止创建子进程的作业对象下运行,并对工作集施加 100 MB 的限制。 由于第三方筛选器可能未正确实现,IFilter 接口的主机隔离过程会提高索引平台的稳定性。
注释
必须写入筛选器处理程序以管理缓冲区并正确堆叠。 所有字符串副本都必须进行显式检查,以防止缓冲区溢出。 应始终验证缓冲区的分配大小。 应始终根据缓冲区的大小测试数据的大小。
IFilter dlls
IFilter DLL 实现 IFilter 接口,使客户端能够从文件类型、类或感知类型中提取文本和属性值信息。 Windows 搜索筛选过程 SearchFilterHost.exe 绑定到为项的类、感知类型或名称扩展注册的 IFilter 。
IFilter 结构
每个 IFilter 都是一个 DLL 文件,它实现进程内组件对象模型 (COM) 服务器以提供指定的筛选功能。 下图演示了典型的 IFilter DLL 的整体结构。 更复杂的示例可以实现多个 IFilter 类。
本机代码
筛选器必须以本机代码编写,因为多个加载项在运行过程中可能存在公共语言运行时 (CLR) 版本控制问题。 在 Windows 7 及更高版本中,以托管代码编写的筛选器将被显式阻止。
查找 IFilter 类标识符
IFilter DLL 的类在 PersistentHandler 注册表项下注册。 以下示例(对于 HTML 文件)说明了如何查找 HTML 文档的 IFilter DLL。 此示例遵循类似于系统用来查找与项关联的 IFilter 的逻辑。
- 检查 DLL 筛选器处理的文件类型的扩展名是否在注册表项 \HKEY_LOCAL_MACHINE\SOFTWARE\Classes 下已注册为 PersistentHandler。 让此键成为
Value1。 如果该条目已存在,请跳到此过程的步骤 4 并在该键中使用Value1。 这些值的类型为REG_SZ。
\HKEY_LOCAL_MACHINE
SOFTWARE
Classes
.htm
PersistentHandler
{EEC97550-47A9-11CF-B952-00AA0051FE20}
- 或者,如果没有为扩展名注册的 PersistentHandler,请在注册表项 \HKEY_LOCAL_MACHINE\SOFTWARE\Classes 下找到与文档类型关联的 CLSID。 让此键成为
Value2。
\HKEY_LOCAL_MACHINE
SOFTWARE
Classes
htmlfile
= Class for WWW HTML files
CLSID
{25336920-03F9-11CF-8FD0-00AA00686F13}
- 确定是否已为 CLSID 注册 PersistentHandler。 使用在步骤 2 中确定的
Value2,查找 \HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\Value2 条目的 PersistentHandler。 让此键成为Value3。
\HKEY_LOCAL_MACHINE
SOFTWARE
Classes
htmlfile
= Class for WWW HTML files
PersistentHandler
{EEC97550-47A9-11CF-B952-00AA0051FE20}
- 确定 IFilter 持久性处理程序 GUID。 使用
Value1和Value3查找文档类型的 IFilter 持久处理程序 GUID。 注册表项 \HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\Value1 或 3\PersistentAddinsRegistered\ 89BCB740-6119-101A-BCB7-00DD010655AF“/> 生成此文档类型的 IFilter PersistentHandler GUID。 让此键成为Value4。 在此示例中, IFilter 接口 GUID 为 89BCB740-6119-101A-BCB7-00DD010655AF。
HKEY_LOCAL_MACHINE
SOFTWARE
Classes
{EEC97550-47A9-11CF-B952-00AA0051FE20}
= HTML File Persistent Handler
Data type REG_SZ
PersistentAddinsRegistered
{89BCB740-6119-101A-BCB7-00DD010655AF}
Data type REG_SZ
default = {E0CA5340-4534-11CF-B952-00AA0051FE20}
注释
在此示例中,HTML 文档的 IFilter DLL 是 nlhtml.dll。
IFilter::GetChunk 和区域设置代码标识符
文本的 LCID 可以在单个文件中更改。 例如,指令手册的文本可能会在英语(en-us)和西班牙语(es)之间交替,或者该文本可能包含一个单词,而不是主要语言。 无论哪种情况,每次 LCID 更改时,IFilter 都必须开始一个新区块。 由于 LCID 被用于选择适当的断字符,因此正确识别 LCID 非常重要。 如果 IFilter 无法确定文本的区域设置,则它应返回包含区块的 LCID 为零。 返回零的 LCID 会导致 Windows 搜索使用语言自动检测(LAD)技术来确定区块的区域设置 ID。 如果 Windows 搜索找不到匹配项,则默认为系统默认区域设置(通过调用 GetSystemDefaultLocaleName 函数函数 )。 有关详细信息,请参阅 IFilter::GetChunk、 CHUNK_BREAKTYPE、 CHUNKSTATE 和 STAT_CHUNK。
如果您掌控文件格式,并且当前其中不包含区域设置信息,建议添加用户功能,以支持正确的区域设置识别。 使用不匹配的断字符可能会导致用户的查询体验不佳。 有关详细信息,请参阅 IWordBreaker。
注释
筛选器与文件类型相关联,如文件扩展名、MIME 类型或 CLSID 所表示。 虽然一个筛选器可以处理多个文件类型,但每种类型只处理一个筛选器。
其他资源
- GitHub 上提供的 IFilterSample 代码示例演示如何创建用于实现 IFilter 接口的 IFilter 基类。
- 有关索引过程的概述,请参阅 “索引过程”。
- 有关文件类型的概述,请参阅 文件类型。
- 若要查询文件类型的文件关联属性,请参阅 PerceivedTypes、SystemFileAssociations 和应用程序注册。