实现 WDS 的协议处理程序

注意

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

创建协议处理程序涉及实现 ISearchProtocol 以管理 UrlAccessor 对象, 实现 IUrlAccessor 生成有关和标识数据存储中项目的相应筛选器的元数据,实现 IProtocolHandlerSite 实例化 SearchProtocol 对象和标识适当的筛选器,以及 实现 IFilter来筛选专有文件或枚举和筛选分层存储的文件。 协议处理程序必须是多线程的。

本部分包含以下主题:

有关 URL 的注释

Microsoft Windows 桌面搜索 (WDS) 使用 URL 来唯一标识文件系统、类似数据库的存储内或 Web 上的项。 定义入口节点的 URL 称为起始页;WDS 从该起始页开始,以递归方式对数据存储进行爬网。 典型的 URL 结构为:

protocol://host/path/name.extension

注意

如果要添加新的数据存储,则需要选择一个名称来标识它与当前数据存储不冲突。 建议使用此命名约定:companyName.scheme。

 

协议处理程序接口

ISearchProtocol

ISearchProtocol 接口调用、初始化和管理 UrlAccessor 对象。 有关实现 ISearchProtocol 接口的详细信息,请参阅 ISearchProtocol 接口参考

IUrlAccessor

对于指定的 URL, IUrlAccessor 接口会生成有关位置结构以及包含项的元数据,并将这些项绑定到筛选器。 IUrlAccessor 对象由 SearchProtocol 对象实例化和初始化;但是,还可以实现内部初始化方法,以便 IUrlAccessor 对象可以执行特定于协议处理程序的初始化任务,例如验证正在访问的项的 URL 或检查上次修改时间以确定文件是否必须在当前爬网中处理。

注意

忽略目录的修改时间。 IUrlAccessor 对象必须枚举子对象,以确定是否有任何修改或删除。

 

UrlAccessor 对象的大部分设计取决于结构是分层的还是基于链接的。 对于分层数据存储, UrlAccessor 对象必须找到可以枚举其内容的筛选器。 分层协议处理程序和基于链接的协议处理程序之间的另一个区别是 IsDirectory 方法的使用。 在基于链接的协议处理程序中,此方法应返回S_FALSE。 分层协议处理程序必须返回容器S_OK。

有关实现 IUrlAccessor 接口的进一步说明,请参阅 IUrlAccessor 接口 参考。

IProtocolHandlerSite

此接口用于实例化 SearchProtocol 对象,并为 UrlAccessor 对象提供针对指定类 ID (CLSID) 的适当筛选器。

用于容器的 IFilters

如果要实现分层协议处理程序,则必须实现枚举表示容器或文件夹的 URL 的容器 IFilter组件。 枚举过程是一个循环,通过 IFilter 接口的 GetChunkGetValue 方法返回表示容器中每个项的 URL 列表。

首先, GetChunk 返回一个 FULLPROSPEC,其中属性集GATHER_PROPSET,

  • PID_GTHR_DIRLINK为项的 URL(不带上次修改时间),或者
  • PID_GTHR_DIRLINK_WITH_TIME,URL 以及上次修改时间

GATHER_PROPSET的属性集 GUID 为 0B63E343-9CCC-11D0-BCDB-00805FCCCE04。 PROPSPEC 属性为 PID_GTHR_DIRLINK=2 或PID_GTHR_DIRLINK_WITH_TIME = 12 个小数。

返回PID_GTHR_DIRLINK_WITH_TIME更高效,因为索引器可以立即确定是否需要为项编制索引,而无需调用 ISearchProtocol-CreateUrlAccessor> () 和 IUrlAccessor-GetLastModified> () 方法。

然后,如果) 使用, GetValue 将返回 URL (和上次修改时间的 PROPVARIANT,如下所示:

  • VT_LPWSTR、子项的 URL,或
  • URL 的向量,后跟 FILETIME

以下示例代码演示如何生成正确的PID_GTHR_DIRLINK_WITH_TIME。

注意

此代码和信息“按原样”提供,不提供任何形式的明示或默示保证,包括但不限于适销性和/或特定用途适用性的默示保证。

版权 (C) Microsoft。 保留所有权利。

 

// params are assumed to be valid

HRESULT GetPropVariantForUrlAndTime(PCWSTR pszUrl, const FILETIME &ftLastModified, PROPVARIANT **ppPropValue)
{
    *ppPropValue = NULL;

    // allocate the propvariant pointer
    *ppPropValue = (PROPVARIANT *)CoTaskMemAlloc(sizeof(*ppPropValue));
    HRESULT hr = *ppPropValue ? S_OK : E_OUTOFMEMORY;

    if (SUCCEEDED(hr))
    {
        PropVariantInit(*ppPropValue);  // zero init the value

        // now allocate enough memory for 2 nested PropVariants.
        // PID_GTHR_DIRLINK_WITH_TIME is an array of 2 PROPVARIANTs
        PROPVARIANT *pVector = (PROPVARIANT *)CoTaskMemAlloc(sizeof(*pVector) * 2);
        hr = pVector ? S_OK : E_OUTOFMEMORY;

        if (SUCCEEDED(hr))
        {
            // set the container PROPVARIANT that it is a vector of 2 PROPVARIANTS
            (*ppPropValue)->vt = VT_VARIANT | VT_VECTOR;
            (*ppPropValue)->capropvar.cElems = 2;
            (*ppPropValue)->capropvar.pElems = pVector;
            PWSTR pszUrlAlloc;
            hr = SHStrDup(pszUrl, &pszUrlAlloc);

            if (SUCCEEDED(hr))
            {
                // now fill the array of PROPVARIANTS
                // put the pointer to the URL into the vector
                (*ppPropValue)->capropvar.pElems[0].vt = VT_LPWSTR; 
                (*ppPropValue)->capropvar.pElems[0].pwszVal = pszUrlAlloc;

                 // put the FILETIME into vector
                (*ppPropValue)->capropvar.pElems[1].vt = VT_FILETIME; 
                (*ppPropValue)->capropvar.pElems[1].filetime = ftLastModified;
            }

            else
            {
                CoTaskMemFree(pVector);
            }
        }
 
        if (FAILED(hr))
        {
            CoTaskMemFree(*ppPropValue);
            *ppPropValue = NULL;
        }
    }
    return S_OK;
}

注意

容器 IFilter组件应始终枚举所有子 URL,即使子 URL 未更改,因为索引器通过枚举过程检测到删除。 如果DIR_LINKS_WITH_TIME中的日期输出指示数据未更改,则索引器不会更新该 URL 的数据。

 

物理 URL 是 UrlAccessor 对象处理的 URL。 如果筛选器未发出用户友好的 DisplayUrl,则 WDS 会将物理 URL 作为搜索结果的一部分显示给用户。 WDS 架构包含两个属性,用于控制向最终用户显示的内容,如下表所示。

GUID PROPSPEC 说明
D5CDD505-2E9C-101B-9397-08002B2CF9AE DisplayFolder 搜索结果中向用户显示的文件夹路径
D5CDD505-2E9C-101B-9397-08002B2CF9AE FolderName 父文件夹的显示名称

 

如果代码未发出 DisplayFolder 或 FolderName,将从 DisplayUrl 计算这些值。 URL 中的正斜杠表示存储或文件系统中的容器。

添加协议处理程序选项功能

要使协议处理程序具有默认起始页 (和入口节点 URL) ,必须实现 ISearchProtocolOptions 接口。 在 WDS 的未来版本中,此接口将提供“选项”对话框的挂钩,以增强用户体验。 此接口提供以下功能:

  • 确定是否满足协议处理程序的要求。 例如,协议处理程序的存储可能需要访问给定应用程序才能正确索引应用程序的数据,但该应用程序不可用。
  • 标识协议处理程序处理项所需的最低要求。 要求可以用用户友好的本地化描述来表示,例如“Microsoft Outlook 2000 或更高版本”。
  • 定义协议处理程序默认应处理的 URL。

ISearchProtocolOptions

下表描述了需要为 ISearchProtocolOptions 接口实现的方法。

方法 说明
CheckRequirements 确定是否满足自定义协议处理程序的最低要求
GetDefaultCrawlScope 返回自定义协议处理程序的指定存储区中的默认 URL 列表
GetRequirements 标识自定义协议处理程序最低要求的用户友好本地化说明

 

参考

通知索引更改

使用 Shell 扩展添加图标、预览和上下文菜单

安装和注册协议处理程序