IFilter 測試套件會驗證您的篩選處理常式。 測試套件會藉由下列方式執行此動作:呼叫 IFilter 方法,並檢查傳回的值是否符合 IFilter 介面規格;並檢查區塊識別碼是否唯一且遞增、 IFilter 介面在重新初始化之後行為一致,以及任何具有無效參數的 IFilter 方法呼叫都會傳回預期的錯誤碼。 測試套件程式也會輸出篩選器所篩選之檔案的輸出,並檢查登錄中的 IFilter 註冊資訊。
本主題的組織方式如下:
備註
如果要安裝檔案類型的新篩選處理常式,作為現有篩選註冊的取代,安裝程式應該儲存目前的註冊,並在卸載新的篩選處理常式時還原它。 缺乏串接過濾器的機制。 因此,新的篩選處理常式負責複寫舊篩選的任何必要功能。
命令列呼叫
IFilter 測試套件包含三個命令列應用程式 - ifilttst.exe、 filtdump.exe和 filtreg.exe ,以及初始化檔案 ifilttst.ini。
這很重要
在 Windows 7 和更新版本中,會明確封鎖以 Managed 程式碼撰寫的篩選。 篩選必須以原生程式碼撰寫,因為執行多個增益集的程式可能會發生公用語言執行階段 (CLR) 版本設定問題。
Ifilttst.exe
ifilttst.exe 程式會執行數個測試來驗證篩選處理常式。 下列範例說明如何從指令行叫用 ifilttst.exe 程式:
ifilttst /i test.htm /l /d /v 1
此範例會執行下列工作:
- 指示程式篩選檔案 test.htm
- 將記錄訊息重新導向至 test.htm.log
- 將傾印訊息導向至 test.htm.dmp
- 將詳細程度設定為 1
若要讓上述指令運作,目前工作目錄中必須有三個檔案: test.htm、 ifilttst.exe和 ifilttst.ini。 下表列出命令列開關。
| 開關和可能的變數 | Description |
|---|---|
| /i 檔案名稱 | 要過濾的輸入檔案或目錄。 檔案名稱可以包含萬用字元 * 和 ?。 |
| /l | 日誌訊息會導向至檔案,而不是畫面。 記錄訊息描述執行的個別測試以及測試的通過/失敗結果。 記錄檔的檔名與輸入檔的檔名相同,但其副檔名為 ".log"。 |
| /d | 傾印訊息會導向至檔案,而不是畫面。 傾印訊息會描述資料區塊的內容。 在詳細程度為 3 時,會輸出區塊結構。 傾印檔案名稱與輸入檔案名稱相同,但副檔名為.dmp。 |
| /-l | 停用記錄。 此標誌會覆寫 /l 開關。 |
| /-d | 停用匯出。 此標誌會覆蓋/d開關。 |
| /v 整數 | 訊息冗繁等級。 預設值為 3。
|
| /t 整數 | 要啟動的執行緒數目。 預設值為 1。 |
| /r 整數] | 遞迴過濾子目錄。 選用的整數參數指定要執行遞迴的深度。 如果未指定整數,或整數為 0,則會假設完全遞迴。 依預設,遞迴深度為 1。 |
| /c 整數 | 循環的次數。 如果整數為 0,則測試無限循環。 依預設,測試只會迴圈一次。 |
備註
您必須在命令列開關與值之間包含空格。
Filtdump.exe
filtdump.exe 程式會載入指定檔的篩選處理常式,並列印 IFilter DLL 所產生的輸出。 下列範例說明如何叫用 filtdump.exe 程式。
filtdump filename.ext
Filtdump.exe 會使用 ILoadFilter::LoadIFilter 方法來載入適用於指定副檔名的 IFilter DLL,並列印結果。 例如,下列命令會指示 filtdump.exe 載入副檔名 .smp 的 smpfilt.dll 篩選處理常式、從檔案 myfile.smp 擷取所有文字和屬性,然後列印結果。
filtdump myfile.smp
Filtreg.exe
filtreg.exe 程式會檢查登錄中的 IFilter 安裝資訊。 您可以鍵入 filtreg.exe 程式的名稱,從命令列呼叫程式,如下列範例所示。
filtreg
Filtreg.exe 會列印檔名延伸部分和它們相關聯的篩選器處理程序的 IFilter DLL 名稱,以列舉所有具有篩選器處理程序相關聯的檔名延伸部分。 這是驗證 IFilter 正確安裝的簡單方法。
Ifilttst.ini
IFilter 介面會藉由呼叫 IFilter::Init 方法來初始化。 IFilter::Init 方法會採用下列四個參數:
- grf旗標
- c屬性
- a屬性
- pdw旗標
IFilter 測試套件的 ifilttst.exe 程式的使用者可以在名為 ifilttst.ini的檔案中指定這些參數的值。 下表說明 ifilttst.ini 檔案中指定前三個參數 (輸入參數) 的項目。 如需範例檔案,請參閱 範例 ifilttst.ini 檔案。
備註
pdwFlags 參數沒有表格條目,因為它是輸出參數,在呼叫 IFilter::Init 方法之前,它不需要有任何特殊值。
| Entry | Description | |
|---|---|---|
| Flags | 要由 OR 運算子聯結的 IFILTER_INIT 旗標名稱,以形成 IFilter::Init 方法的 grfFlags 參數。 旗標名稱必須全部為大寫,且在同一行。 | |
| c屬性 | 代表 cAttributes 參數值的十進位整數。 | |
| a屬性 | 此項目必須以 aAttributes 開頭,且必須與區段內的其他 aAttributes 項目不同。
aAttributes 項目的合法名稱為:aAttributes、aAttributes1、aAttributes2 等等。 第一個權杖必須是 GUID。 GUID 的格式必須完全符合[Test3]區段中所示。 第二個標記可以是屬性識別碼(PID),包括以十六進位表示的數字,或是寬字串(lpwstr)的指標。 lpwstr 可以透過將字串括在雙引號中來指定,如範例 ifilttst.ini 檔案的區段所示 [Test6] 。 |
如果未指定 Flags 和 cAttributes 專案,則預設為 0。 如果您將 cAttributes 設定為等於 2,則應指定兩個 aAttributes 名稱。 在範例的區段中 [Test5] , cAttributes 是 1,但尚未指定 aAttributes 。 然後,測試會呼叫 IFilter::Init 方法,其中 cAttributes 等於 1,aAttributes 等於 NULL。 這是有用的測試案例,因為它可能會導致 IFilter::Init 方法中的存取違規。
如果 ifilttst.exe 在工作目錄中找不到名為 ifilttst.ini 的檔案,則會使用預設設定來初始化 IFilter::Init 物件。 下列範例說明預設組態。
[default]
grfFlags = IFILTER_INIT_APPLY_INDEX_ATTRIBUTES
cAttributes = 0
範例 ifilttst.ini 檔案
ifilttst.ini 檔案會以區段組織,區段名稱括在方括號中。 在此範例中,區段的名稱為 [Test1]、 、 [Test2]依此類推。 所有區段名稱都必須是唯一的。 測試會從第一個區段讀取值,並使用這些值初始化 IFilter 。 然後,所有測試都會使用此 IFilter 設定來執行。 然後,會使用上面列出的參數釋放並重新初始化 IFilter 。 重複此過程,直到測試所有配置為止。
; Only extract text from the object
[Test1]
Flags =
cAttributes = 0
// Get all attributes (text-type and internal value-type properties.
[Test2]
Flags = IFILTER_INIT_APPLY_INDEX_ATTRIBUTES
cAttributes = 0
// This also extracts just text from the object (the GUID is PSGUID_STORAGE, and the propid is
// PID_STG_CONTENTS).
[Test3]
Flags = IFILTER_INIT_CANON_PARAGRAPHS IFILTER_INIT_HARD_LINE_BREAKS
cAttributes = 1
aAttributes1 = b725f130-47ef-101a-a5f1-02608c9eebac 13
// Only extract requested attribute from the html object (the GUID corresponds to the HTML IFilter.
[Test4]
Flags = IFILTER_INIT_CANON_HYPHENS IFILTER_INIT_CANON_SPACES
cAttributes = 1
aAttributes1 = 70eb7a10-55d9-11cf-b75b-00aa0051fe20 2
// Question: what happens if cAttributes is nonzero, but aAttributes is empty?
[Test5]
Flags = IFILTER_INIT_CANON_SPACES IFILTER_INIT_APPLY_INDEX_ATTRIBUTES IFILTER_INIT_APPLY_OTHER_ATTRIBUTES
cAttributes = 1
// Here is an attribute with a lpwstr instead of a propid (the lpwstr is enclosed in quotes).
// The GUID corresponds to the meta tag clsid for the HTML IFilter.
[Test6]
Flags =
cAttributes = 1
aAttributes1 = D1B5D3F0-C0B3-11CF-9A92-00A0C908DBF1 "GENERATOR"
IFilter 測試程序
初始化 IFilter 之後,ifilttst.exe 程式會在 IFilter 上執行一系列測試。 除了遵循 IFilter 測試程式之外,請確定您的 IFilter 實作採用安全的程式代碼做法。 請參閱 在 Windows 搜尋中實作篩選處理常式中的「Windows 搜尋的安全程式碼做法」。
驗證測試
驗證測試會一次檢查一個區塊,驗證每一個個別區塊及所有返回碼。 驗證測試會將所有傳回的 STAT_CHUNK 結構儲存在清單中。
驗證測試會驗證下列條件:
- STAT_CHUNK。idChunk 區塊 ID 必須是唯一的且遞增。
- STAT_CHUNK。flags 參數是可辨識的區塊狀態,例如 CHUNKSTATE、CHUNK_TEXT 或 CenabledHUNK_VALUE 常數。
- STAT_CHUNK。breakType 參數是可辨識的中斷類型 (0, 1, 2, 3, 4)。
- 如果 IFilter 初始化屬性指定 IFilter 應該只傳回包含內部值類型屬性的區塊,則 idChunkSource 必須等於 0。
- 如果區塊不是衍生的,也就是說,如果它不是內部值類型屬性,則 STAT_CHUNK。idChunkSource 必須等於 STAT_CHUNK。idChunk。
- IFilter::GetChunk 會傳回S_OK或其他可接受的傳回值,例如 FILTER_E_END_OF_CHUNKS、FILTER_E_LINK_UNAVAILABLE 等等。
- 如果區塊包含文字, IFilter::GetText 會傳回 S_OK、FILTER_S_LAST_TEXT 或 FILTER_E_NO_MORE_TEXT。
- 如果 IFilter::GetText 傳回 FILTER_S_LAST_TEXT,則 IFilter::GetText 的下一個呼叫會傳回 FILTER_E_NO_MORE_TEXT。
- 如果區塊包含值, IFilter::GetValue 會傳回 S_OK 或 FILTER_E_NO_MORE_VALUES。
一致性測試
ifilttxt.exe 程式會使用與驗證測試相同的參數重新初始化 IFilter 介面,並執行一致性測試。 如果 IFilter 實作已使用 IFILTER_INIT IFILTER_INIT_INDEXING_ONLY 旗標初始化,測試會釋放 IFilter 介面,並在再次呼叫 IFilter::Init 方法之前重新系結它。
一致性測試會驗證下列條件:
- IFilter::GetChunk 方法所傳回的每個STAT_CHUNK結構都與驗證測試中傳回的對應STAT_CHUNK相同。
- IFilter::GetChunk 會傳回S_OK或其他可接受的傳回值,例如 FILTER_E_END_OF_CHUNKS、FILTER_E_LINK_UNAVAILABLE 等等。
輸入測試無效
ifilttst.exe 程式會使用相同的參數重新初始化 IFilter 介面,並執行無效的輸入測試。 此測試會逐步執行文件,一次一個區塊,進行不正確的函式呼叫,例如當當前區塊內容為文字時呼叫 IFilter::GetValue 方法。 測試會檢查所有傳回碼是否符合 IFilter 規格。
無效的輸入測試會驗證下列條件:
- 如果目前區塊包含文字, IFilter::GetValue 會傳回 FILTER_E_NO_VALUES,而且呼叫 IFilter::GetText 會成功。
- 如果目前的區塊包含值,則 IFilter::GetText 會傳回 FILTER_E_NO_TEXT,而且呼叫 IFilter::GetValue 會成功。
- 如果先前呼叫 IFilter::GetText 傳回FILTER_E_NO_MORE_TEXT,則連續呼叫 IFilter::GetText 會傳回 FILTER_E_NO_MORE_TEXT。
- 如果先前呼叫 IFilter::GetValue 傳回FILTER_E_NO_MORE_VALUES,則連續呼叫 IFilter::GetValue 會傳回 FILTER_E_NO_MORE_VALUES。
- 如果先前呼叫 IFilter::GetChunk 傳回 FILTER_E_END_OF_CHUNKS,則連續呼叫 IFilter::GetChunk 會傳回FILTER_E_END_OF_CHUNKS。
備註
無效的輸入測試會將目前的區塊結構與驗證測試中傳回的區塊結構進行比較,以確保它們相同。
測試不同的 IFilter 設定
ifilttst.exe 程式會釋放 IFilter 介面並重新系結,這次會使用下一組參數來初始化它。 測試會重複進行一系列循環:驗證測試、一致性測試和無效輸入測試,直到所有在 ifilttst.ini 檔案中指定的 IFilter 設定都已完成測試為止。
確保已註冊的項目已編製索引
IFilter 的最終測試可確保 IFilter 已正確註冊,並叫用它來索引您註冊以使用它的專案。 您可以使用型錄管理員來啟動重新編索引,或使用抓取範圍管理員 (CSM) 設定預設規則來指定索引器要抓取的 URL。 索引完成之後,請使用 Windows 搜尋 UI 在專案的內容或屬性中搜尋字串。 如果項目已編製索引,它們將出現在搜尋結果中。
如需重新編製索引的詳細資訊,請參閱 使用型錄管理員 和 使用編目範圍管理員。 ReindexMatchingUrls 程式碼範例示範如何指定要重新編製索引的檔案以及重新編製索引的方法。 CrawlScopeCommandLine 程式碼範例示範如何定義編目範圍管理員 (CSM) 索引作業的命令列選項。 這兩個程式碼範例都可以在 GitHub 上取得。
範例記錄檔
根據要求,Ifilttst.exe 程式可以產生日誌,其中包含執行期間所採取步驟的描述。 下列範例是記錄檔的摘錄,詳細程度設定為可能的最高值 3。
1. INFO----**** New configuration ****
2.
3. Section name : Test2
4. grfFlags : 63
5. cAttributes : 0
6. aAttributes : NONE
7. pdwFlags : 0
8.
9. INFO----Successfully bound filter.
10.
11. PASS----Init() returned a valid value for pdwFlags.
12.
13. INFO----Successfully initialized filter.
14.
15. INFO----Performing validation test. In this part of the test, the chunks structures
16. returned by the IFilter are checked for correctness, and the return values
17. of the IFilter calls are checked.
18.
19. PASS----GetChunk() succeeded.
20.
21. PASS----The current chunk has a legal value for the flags field.
第一行是參考訊息,指出已從 ifilttst.ini 檔案載入新配置。 第 (3) 行表示已從中讀取目前組態的 ifilttst.ini 檔案中的區段名稱。 第 (4) 行到 (7) 會列出 IFilter::Init 的參數。
INFO 開頭的行是關於 IFilter 系結和驗證測試開始的信息性訊息。 開 PASS 頭的行是有關已通過的特定測試的訊息。
下列記錄範例中的行是警告。 警告提醒人們注意有問題的 IFilter 行為,儘管是合法的。 此警告表示 IFilter::GetChunk 方法已傳回不包含文字的文字區塊。
WARNING-First call to GetText() returned FILTER_E_NO_MORE_TEXT.
下列範例錯誤訊息指出 IFilter 發出未要求的區塊。
ERROR---The IFilter has emitted a chunk which it was not requested to emit.
Check the initialization parameters in section Test1 of the initialization file.
INFO----Current chunk propid : 0x5
在此範例錯誤訊息的情況下, IFilter 發出 PID 為 0x5的區塊。 檢查 ifilttst.ini 中的區段 [Test1] 會顯示 IFilter 已設定為不會發出具有此 PID 的區塊。 例如,如果 Flags 專案中未指定 IFILTER_INIT_APPLY_INDEX_ATTRIBUTES 或 IFILTER_INIT_APPLY_OTHER_ATTRIBUTES,而且 cAttributes 為 0,則 IFilter 只會發出 PID 為 0x13 且對應至 PID_STG_CONTENTS 的區塊。
範例轉儲檔案
根據要求,Ifilttst.exe 程式可以匯出包含其找到的區塊及其內容的資料。 下列範例是這類轉儲檔案的片段。
1. Chunk ID: ........... 2
2. Chunk Break Type: ... END OF SENTENCE
3. Chunk State: ........ TEXT
4. Chunk Locale: ....... 0x411
5. Chunk Source ID: .... 2
6. Chunk Start Source .. 0x0
7. Chunk Length Source . 0x0
8. GUID ................ b725f130-47ef-101a-a5f1-02608c9eebac
9. Property ID ......... 0x13
10. This is a HTML IFilter test page
11. Chunk ID: ........... 3
12. Chunk Break Type: ... END OF SENTENCE
13. Chunk State: ........ TEXT
14. Chunk Locale: ....... 0x411
15. Chunk Source ID: .... 2
16. Chunk Start Source .. 0x0
17. Chunk Length Source . 0x0
18. GUID ................ f29f85e0-4ff9-1068-ab91-08002b27b3d9
19. Property ID ......... 0x2
20. This is a HTML IFilter test page
21. Chunk ID: ........... 4
22. Chunk Break Type: ... END OF SENTENCE
23. Chunk State: ........ VALUE
24. Chunk Locale: ....... 0x411
25. Chunk Source ID: .... 2
26. Chunk Start Source .. 0x0
27. Chunk Length Source . 0x0
28. GUID ................ f29f85e0-4ff9-1068-ab91-08002b27b3d9
29. Property ID ......... 0x2
30. This is an HTML IFilter test page
前九行描述了當前的區塊結構。 GUID 和 PID 對應於 PSGUID_STORAGE/PID_STG_CONTENTS。 這是一個包含純文字的區塊。 文字採用下列區塊結構:
10. This is an HTML IFilter test page
下一個區塊從第 11 行開始,具有不同的 GUID,該 GUID 對應於 HTML IFilter,以及不同的 PID,該 PID 對應於 HTML HREF。 這是內部值類型屬性,由HTML IFilter輸出。
下一個區塊從第 21 行開始,具有相同的 GUID 和 PID,但其區塊狀態是 VALUE而不是TEXT。 請注意,最後兩個區塊中的文字與第一個區塊的文字相同。 但是,由於 IFilter 是針對三個屬性 (純文字、HTML HREF 作為文字,以及 HTML HREF 作為值) 所設計,以套用至此片語,因此結果會在三個不同的區塊中發出。
其他資源
- GitHub 上提供的 IFilterSample 程式碼範例示範如何建立 IFilter 基類來實作 IFilter 介面。
- 如需索引程序的概觀,請參閱 索引程序。
- 如需檔案類型的概觀,請參閱 檔案類型。
- 若要查詢檔案類型的檔案關聯屬性,請參閱 PerceivedTypes、SystemFileAssociations 和 Application Registration。