在 Windows 搜索中实现筛选器处理程序
请务必了解筛选器处理程序的所需 DLL 结构, (实现 IFilter 接口) 。
本主题的组织方式如下:
实现和导出 DLL 入口点
本部分中由 Ifilter.dll 表示的每个 IFilter DLL (,) 必须实现并导出以下入口点。 这些入口点通常使用 IFilter 接口的模块定义 (.def) 文件或使用 __declspec (dllexport) 关键字 (keyword) 导出。 DLL 文件可以注册为在任何文件夹中,但它通常驻留在 %SystemRoot%\system32 文件夹中。
下表中列出了并描述了 DLL 入口点。
DLL 名称 | DLL 说明 |
---|---|
DllRegisterServer |
DllRegisterServer 入口点将 DLL 注册为注册表中的筛选器。 通过使用 IFilter 接口 DLL 文件名作为参数运行 regsvr32.exe 程序来注册 DLL: regsvr32.exe %SystemRoot%\system32\Ifilter.dll |
DllUnregisterServer 函数 |
DllUnregisterServer 函数入口点将 DLL 作为注册表中的永久性处理程序删除。 通过使用 标志运行 regsvr32.exe 程序 /u 来注销 DLL: regsvr32.exe /u %SystemRoot%\system32\Ifilter.dll |
DllGetClassObject 函数 | 内容索引客户端通过组件对象模型 (COM) 调用 DllGetClassObject 函数 入口点,为 IFilter 接口创建类工厂对象,并获取指向该对象的类工厂接口的指针。 |
DllCanUnloadNow 函数 | 内容索引客户端通过 COM 调用 DllCanUnloadNow 函数 入口点,以确定是否可以卸载 IFilter DLL。 IFilter 接口在一段时间间隔内未使用后卸载,由 FilterIdleTimeOut 注册表值指定。 |
实现 IFilter 类和类工厂
至少两个类(如 CFilter 和 CFilterCF)通常由每个 IFilter DLL 实现。 CFilter 类生成实现内容筛选功能的 IFilter 接口对象。 其成员函数实现 IFilter 接口的接口方法。 每个 IFilter 类都需要一个唯一的类标识符 (CLSID) , IFilter 接口实现程序会生成该标识符。
CFilterCF 类为 IFilter 接口生成类工厂对象。 类工厂由 DLL 的 DllGetClassObject 函数入口点通过其 IClassFactory 接口调用。 CFilterCF 类创建 CFilter 对象并返回指向 IUnknown 的指针。 在更复杂的情况下, IFilter 可以实现类层次结构来取代单个 CFilter 类。
继承 COM 接口
Windows 搜索 3.0 及更高版本要求使用 IPersistStream ,原因如下:
- 确保性能和将来的兼容性。
- 帮助提高安全性。 使用 IPersistStream 实现的 IFilters 更安全,因为运行 IFilter 接口的上下文不需要在磁盘上或通过网络打开文件的权限。
- 虽然 Windows 搜索仅使用 IPersistStream, 但 IFilter 接口类也可以继承 IPersistFile 接口 和/或 IPersistStorage 接口 接口实现以实现向后兼容性。
这些接口在 mssdk\include 目录中包含的文件中声明,并且具有预定义的接口标识符 (IID) 。 内容索引客户端通过 IUnknown 查询 IFilter 接口,以确定筛选内容时要使用的这些接口。
实现 COM 接口方法
IFilter 接口为 IFilter 接口类和 IFilter 接口类工厂实现 IUnknown 方法。 下表按 vtable 顺序列出了 IFilter 接口应实现的 IFilter 接口特定接口和方法。 IFilter 接口必须至少实现 IPersistStream,但可以实现其他 IPersist 派生的接口。
COM 接口 | 方法 |
---|---|
IClassFactory 接口 | CreateInstance、LockServer |
IClassFactory2 接口 | GetLicInfo、RequestLicKey、CreateInstanceLic |
IFilter | IFilter::Init、 IFilter::GetChunk、 IFilter::GetText、 IFilter::GetValue、 IFilter::BindRegion |
IPersist 接口 | GetClassID |
IPersistFile 接口 | IsDirty、Load、Save、SaveCompleted、GetCurFile |
IPersistStorage 接口 | IsDirty、Load、Save、GetSizeMax |
IPersistStream | IsDirty、Load、Save、GetSizeMax |
每个方法的引用页指定该方法的参数和功能行为。 每个引用页还提供要为该方法实现的结果代码。 IFilter 方法的参考页提供了要实现FACILITY_ITF结果代码中的特定于接口的代码,内容索引客户端还可以处理任何泛型结果代码,例如FACILITY_NULL和FACILITY_WIN32。 有关详细信息,请参阅 COM 错误代码的结构。
未实现的 COM 方法
IFilter 接口必须至少实现 IPersistStream,但不需要实现其他 IPersist 派生的接口。
Windows 搜索不需要实现下表中列出的 COM 方法。
不需要的方法 | 说明 |
---|---|
IPersistStream::IsDirty | 筛选器应返回E_NOTIMPL。 |
IPersistStream::Save | 筛选器应返回E_NOTIMPL。 |
IPersistStream::GetSizeMax | 筛选器应返回E_NOTIMPL。 |
IFilter::BindRegion | 筛选器应返回E_NOTIMPL。 |
其他资源
- GitHub 上提供的 IFilterSample 代码示例演示如何创建用于实现 IFilter 接口的 IFilter 基类。
- 有关索引过程的概述,请参阅 索引过程。
- 有关文件类型的概述,请参阅 文件类型。
- 若要查询文件类型的文件关联属性,请参阅 PerceivedTypes、SystemFileAssociations 和应用程序注册。