フィルター ハンドラーのテスト

IFilter テスト スイートは、フィルター ハンドラーを検証します。 テスト スイートでは、 IFilter メソッドを呼び出し、返された値が IFilter インターフェイス仕様に準拠していないか確認します。チャンク識別子が一意で増加していること、再初期化後 に IFilter インターフェイスが一貫して動作し、無効なパラメーターを持つ IFilter メソッドの呼び出しによって予期されるエラー コードが返されることを確認します。 テスト スイート プログラムは、フィルター ハンドラーによってフィルター処理されたファイルの出力もダンプし、レジストリの IFilter 登録情報を確認します。

このトピックは次のように構成されています。

注

ファイルの種類の新しいフィルター ハンドラーが既存のフィルター登録の代わりにインストールされている場合、インストーラーは現在の登録を保存し、新しいフィルター ハンドラーがアンインストールされた場合は復元する必要があります。 フィルターをチェーンするメカニズムはありません。 そのため、新しいフィルター ハンドラーは、古いフィルターの必要な機能をレプリケートする役割を担います。

コマンド ライン呼び出し

IFilter テスト スイートは、 ifilttst.exe、filtdump.exe、 filtreg.exe 、初期化ファイルの 3 つのコマンド ライン アプリケーション で構成ifilttst.ini。

Important

Windows 7 以降では、マネージド コードで記述されたフィルターは明示的にブロックされます。 複数のアドインが実行されるプロセスで共通言語ランタイム (CLR) のバージョン管理の問題が発生する可能性があるため、フィルターはネイティブ コードで記述する必要があります。

Ifilttst.exe

ifilttst.exe プログラムは、フィルター ハンドラーを検証するために複数のテストを実行します。 次の例は、コマンド ラインから ifilttst.exe プログラムを呼び出す方法を示しています。

ifilttst /i test.htm /l /d /v 1

この例では、次のタスクを実行します。

  • ファイルをフィルター処理するようにプログラムに指示 test.htm
  • ログ メッセージを test.htm.log にリダイレクトします
  • ダンプ メッセージを test.htm.dmp にリダイレクトします
  • 詳細度を 1 に設定します。

上記のコマンドを機能させるには、現在の作業ディレクトリに 3 つのファイル ( test.htm、 ifilttst.exe、 ifilttst.ini) が存在する必要があります。 コマンド ライン スイッチを次の表に示します。

切り替えと使用可能な変数 Description
/i ファイル名 フィルター処理する入力ファイルまたはディレクトリ。 ファイル名には、ワイルドカード文字 * および ?を含めることができます。
/l ログ メッセージは、画面ではなくファイルに送信されます。 ログ メッセージには、実行された個々のテストと、テストの合格/失敗結果が記述されています。 ログ ファイル名は入力ファイル名と同じですが、拡張子は .log です。
/d ダンプ メッセージは、画面ではなくファイルに転送されます。 ダンプ メッセージは、チャンクの内容を記述します。 詳細レベルが 3 の場合、チャンク構造がダンプされます。 ダンプ ファイル名は入力ファイル名と同じですが、拡張子は .dmp です。
/-l ログ記録を無効にします。 このフラグは、 /l スイッチをオーバーライドします。
/-d ダンプを無効にします。 このフラグは、 /d スイッチをオーバーライドします。
/v 整数 冗長度レベル。 デフォルトは3です。
  • 0 - テストでは、特定の IFilter インターフェイスエラーに関するメッセージのみがログに記録されます。 テストによりチャンク内容をダンプします。
  • 1 - テストでは、警告メッセージとレベル 0 の警告メッセージがログに記録されます。
  • 2 - テストは、合格したテストとレベル 1 のテストに関するメッセージをログに記録します。
  • 3 - テストでは、情報メッセージとレベル 2 のメッセージがログに記録されます。 さらに、テストはチャンクの構造を出力します。
/t integer 起動するスレッドの数。 既定値は 1 です。
/r integer] サブディレクトリを再帰的にフィルター処理します。 省略可能な整数パラメーターは、再帰を実行する深さを指定します。 整数が指定されていない場合、または整数が 0 の場合は、完全再帰が想定されます。 既定では、再帰の深さは 1 です。
/c 整数 ループする回数。 整数が 0 の場合、テストは無限にループします。 既定では、テストは 1 回だけループします。

注

コマンド ライン スイッチと値の間にスペースを含める必要があります。

Filtdump.exe

filtdump.exe プログラムは、指定したドキュメントのフィルター ハンドラーを読み込み、 IFilter DLL によって生成された出力を出力します。 次の例は、filtdump.exe プログラムを呼び出す方法を示しています。

filtdump filename.ext

Filtdump.exe は 、ILoadFilter::LoadIFilter メソッドを使用して、指定したファイル名拡張子に適した IFilter DLL を読み込み、結果を出力します。 たとえば、次のコマンドは、拡張子 .smp の smpfilt.dll フィルター ハンドラーを読み込み、myfile.smp ファイルからすべてのテキストとプロパティを抽出し、結果を出力するように filtdump.exe に指示します。

filtdump myfile.smp

Filtreg.exe

filtreg.exe プログラムは、レジストリ内の IFilter インストール情報を検査します。 コマンド ラインから filtreg.exe プログラムを呼び出すには、次の例のように名前を入力します。

filtreg

Filtreg.exe は、ファイル名拡張子と拡張子の IFilter DLL の名前を印刷することによって、フィルター ハンドラーが関連付けられているすべてのファイル名拡張子を列挙します。 これは、 IFilter の正しいインストールを確認する簡単な方法です。

Ifilttst.ini

IFilter インターフェイスは、IFilter::Init メソッドを呼び出すことによって初期化されます。 IFilter::Init メソッドは、次の 4 つのパラメーターを受け取ります。

  1. grfFlags
  2. cAttributes
  3. aAttributes
  4. pdwFlags

IFilter テスト スイートの ifilttst.exe プログラムのユーザーは、ifilttst.iniというファイルでこれらのパラメーターの値を指定できます。 次の表では、最初の 3 つのパラメーター (入力パラメーター) を指定する ifilttst.ini ファイル内のエントリについて説明します。 サンプル ファイルについては、「 サンプル ifilttst.ini ファイル」を参照してください。

注

pdwFlags パラメーターは出力パラメーターであるため、テーブル エントリはありません。IFilter::Init メソッドを呼び出す前に特別な値を指定する必要はありません。

  エントリ Description
Flags IFilter::Init メソッドの grfFlags パラメーターを形成するために OR 演算子によって結合されるIFILTER_INIT フラグの名前。 フラグ名はすべて大文字で、同じ行に置く必要があります。
cAttributes cAttributes パラメーターの値を表す 10 進整数。
aAttributes このエントリは aAttributes で始まる必要があり、セクション内の他の aAttributes エントリとは異なる必要があります。 aAttributes エントリの有効な名前は、aAttributes、aAttributes1、aAttributes2 などです。 最初のトークンは GUID である必要があります。 GUID は、[Test3]の セクションに示されているとおりに書式設定する必要があります。 2 番目のトークンには、16 進表記の数値で構成されるプロパティ識別子 (PID) またはワイド文字列 (lpwstr) へのポインターを指定できます。 lpwstr は、サンプル ifilttst.ini ファイルの [Test6] セクションに示すように、文字列を二重引用符で囲むことで指定できます。

Flags エントリと cAttributes エントリが指定されていない場合、既定値は 0 になります。 cAttributes を 2 に設定する場合は、2 つの aAttributes 名を指定する必要があります。 サンプルの [Test5] セクションでは、 cAttributes は 1 ですが、 aAttributes は指定されていません。 次に、cAttributes が 1 で、aAttributes が NULL である IFilter::Init メソッドを呼び出します。 これは、 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 Search での フィルター ハンドラーの実装」の「Windows Search のセキュリティで保護されたコード プラクティス」を参照してください。

検証テスト

検証テストでは、一度に 1 つのチャンクずつオブジェクトをステップ実行し、個々のチャンクとすべてのリターン コードを検証します。 検証テストでは、返されたすべての STAT_CHUNK 構造体が一覧に保存されます。

検証テストでは、次の条件が検証されます。

  • STAT_CHUNK。idChunk チャンク ID は一意であり、増加している必要があります。
  • STAT_CHUNK。flags パラメーターは、CHUNKSTATE、CHUNK_TEXT、またはCenabledHUNK_VALUE定数など、認識されるチャンク状態です。
  • STAT_CHUNK。breakType パラメーターは、認識される break 型 (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 インターフェイスを再初期化し、無効な入力テストを実行します。 現在のチャンクにテキストが含まれている場合など、誤った関数呼び出しを行いながら、1つずつ順番にドキュメントを処理するこのテストでは、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 が正しく登録されていること、および IFilter を使用するために登録した項目のインデックスを作成するために呼び出されることが確認されます。 カタログ マネージャーを使用してインデックスの再作成を開始するか、クロール スコープ マネージャー (CSM) を使用して、インデクサーでクロールする URL を示す既定のルールを設定できます。 インデックス作成が完了したら、Windows Search 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 でチャンクを出力しないように構成されたことが示されます。 たとえば、フラグ エントリで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

最初の 9 行は、現在のチャンク構造を表します。 GUID と PID は、PSGUID_STORAGE/PID_STG_CONTENTSに対応します。 これはプレーンテキストを含むチャンクです。 テキストは次のチャンク構造です。

10. This is an HTML IFilter test page

11 行目以降の次のチャンクには、HTML IFilter に対応する異なる GUID と、HTML HREF に対応する別の PID が含まれています。 これは、 HTML IFilterによってエクスポートされる内部値型プロパティです。

次のチャンク (21 行目以降) の GUID と PID は同じですが、チャンクの状態はVALUEではなくTEXT。 これら最後の 2 つのチャンク内のテキストは、最初のチャンクのテキストと同じであることに注意してください。 ただし、IFilter は、このフレーズに適用される 3 つの属性 (プレーン テキスト、テキストとしての HTML HREF、値としての HTML HREF) 用に設計されているため、結果は 3 つの個別のチャンクで出力されます。

その他のリソース

フィルター ハンドラーの開発

Windows Search のフィルター ハンドラーについて

Windows Search でフィルター ハンドラーを作成するためのベスト プラクティス

フィルター ハンドラーからプロパティを返す

Windows に付属するフィルター ハンドラー

Windows Search でのフィルター ハンドラーの実装

フィルター ハンドラーの登録