共用方式為


開發 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結構中的資訊,包括單調增加區塊標識符、目前區塊與上一個區塊相關的狀態資訊、旗標,指出區塊是否包含文字或值。 區塊的地區設定和區塊的屬性規格。 屬性規格是包含 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 釋放 PROPVARIANT 結構本身。 如需有關 PROPVARIANT 的詳細資訊,請參考 PROPVARIANT

屬性值

篩選條件應該至少輸出下列屬性,這些屬性是 WDS 結果檢視中的預設數據行。

全球唯一識別碼 (GUID) PROPSPEC 友好的名稱 描述
F29F85E0-4FF9-1068-AB91-08002B27B3D9 2 主要標題 顯示此項目的標題。
F29F85E0-4FF9-1068-AB91-08002B27B3D9 4 主要作者 與此專案最相關的人員。
D5CDD505-2E9C-101B-9397-08002B2CF9AE 主要日期 主要日期 對於項目的最重要日期,例如電子郵件的接收日期或檔案的修改日期。
D5CDD505-2E9C-101B-9397-08002B2CF9AE 感知類型 感知類型 正在剖析的文件類型。 必須符合 WDS 中列出的 Windows 桌面搜尋的其中一個類型 感知類型

 

對於純文本專案,WDS 會擷取所有文字及系統定義的屬性,例如檔案大小或副檔名,並在索引過程中包括新增的純文本文件類型。 可以傳回至索引的其他屬性類型包括:

  • 檔案:作者、標題、狀態、關鍵詞
  • 針對媒體:專輯、內容類型、相機製作、拍攝日期
  • 針對通訊:寄件者、收件者、副本、重要性
  • 聯繫人:職稱、商務電話、公司

上述清單會將指定感知類型通用的屬性分組;不過,不論類型為何,都可以使用任何屬性。 例如,公司可以用於聯絡人的僱主名稱,也可以用於與檔案相關的客戶名稱。 其中許多屬性可用來在 WDS 結果檢視中顯示搜尋結果。 例如,檔案的 Title 屬性會顯示為預設結果檢視中的主數據行。 IFilter 物件應該輸出與剖析之專案類型相關的所有屬性。 無法在 WDS 2.x 中新增自訂屬性。 如需可用屬性的完整清單,請參閱 WDS 架構

外掛程式安裝

安裝篩選器牽涉到將 DLL 複製到 Program Files 目錄中的適當位置,並註冊它。 過濾器應實現安裝時的自主註冊,並應遵循下列指導方針:

  • 安裝程序必須使用 EXE 或 MSI 安裝程式。
  • 必須提供更新說明。
  • 必須為每個安裝的外掛建立 新增/移除程式 項目。
  • 安裝程式必須接管目前外掛程式所瞭解之特定檔類型或儲存設定的所有登錄檔設定。
  • 如果覆寫先前的外掛程式,安裝程式應通知使用者。
  • 如果較新的外掛程式覆蓋了先前的外掛程式,應該能夠還原先前外掛程式的功能,並再次將它設定為該文件類型或存放區的預設外掛程式。

註冊所需的 CLSID

每個篩選都有三個類別標識碼或CLSID相關聯。 您必須產生一或多個(使用 uuidgen.exe)來登錄您的篩選附加元件。

  • 第一個會識別所有篩選條件的持續性處理程式 IID_IFilter,也就是 {89BCB740-6119-101A-BCB7-00DD010655AF}。 這個 CLSID 是實作 IFilter 的所有篩選條件的常數。
  • 第二個 (IID_IFilter 鍵的值) 會識別檔類型的 IFilter 實作。 此索引鍵包含 InprocServer32 值,依路徑和線程模型指定 DLL 名稱。 如果篩選條件位於系統路徑中,例如 system32 目錄,檔名就已足夠。 否則,此值應該具有完整的路徑規格。
  • 第三個會識別篩選程式的檔類型,並由IPersist介面上的 GetClassID 方法傳回。

注意

在未來版本的Microsoft作系統中,在 system32 目錄中安裝檔案可能會變得更困難,因此我們建議您在 Program Files 下安裝它們,並在登錄中包含篩選的完整路徑。 基於安全性考慮,在登錄中指定 DLL 的完整路徑也是謹慎的做法。 否則,如果您的 DLL 的「特洛伊木馬」版本碰巧位於進程路徑中並且排在您的版本之前,它可能會被載入。

 

註冊模型

當WDS準備好篩選檔案時,它會在檔案擴展名下的登錄中尋找,以判斷要載入的篩選。 然後,它會遵循一系列登錄連結,依下列順序尋找篩選 DLL 的名稱:

  1. 從位於的 CLSID:

    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

要註冊篩選外掛

您必須在註冊表中建立八個註冊表項,以註冊篩選外掛程式,其中:

  • .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