Поделиться через


Тестирование обработчиков фильтров

Набор тестов IFilter проверяет обработчики фильтров. Набор тестов делает это путем вызова методов IFilter и проверки возвращаемых значений на соответствие спецификации интерфейса IFilter IFilter, а также проверяет, что идентификаторы блоков уникальны и возрастают, что интерфейс IFilter ведет себя последовательно после повторной инициализации, и что все вызовы методов IFilter с недопустимыми параметрами возвращают ожидаемые коды ошибок. Программы набора тестов также сбрасывают выходные данные файла, отфильтрованного обработчиком фильтра, и проверьте сведения о регистрации IFilter в реестре.

Этот раздел организован следующим образом:

Заметка

Если новый обработчик фильтра для типа файла устанавливается в качестве замены существующей регистрации фильтра, установщик должен сохранить текущую регистрацию и восстановить его, если новый обработчик фильтра удален. Нет механизма для объединения фильтров. Таким образом, новый обработчик фильтра отвечает за репликацию всех необходимых функций старого фильтра.

Command-Line Вызов

Набор тестов IFilter состоит из трех приложений командной строки — ifilttst.exe, filtdump.exeи filtreg.exe и файла инициализации, ifilttst.ini.

Важно

В 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

Для работы предыдущей команды три файла должны находиться в текущем рабочем каталоге: test.htm, ifilttst.exeи ifilttst.ini. Параметры командной строки перечислены в следующей таблице.

Переключение и возможные переменные Описание
/i имя файла Входной файл или каталог для фильтрации. Имя файла может содержать подстановочные знаки * и ?.
/l Сообщения журнала направляются в файл вместо экрана. Сообщения журнала описывают отдельные тесты и результаты прохождения или сбоя тестов. Имя файла журнала совпадает с именем входного файла, но с расширением .log.
/d Сообщения дампа направляются в файл вместо экрана. Сообщения дампа описывают содержимое блоков. Структура блока сбрасывается, когда уровень детализации равен 3. Имя файла дампа совпадает с именем входного файла, но с расширением .dmp.
/-l Отключите логирование. Этот флаг переопределяет переключатель /l.
/-d Отключите дамп. Этот флаг переопределяет переключатель /d.
/v целое число Уровень детализации. Значение по умолчанию — 3.
  • 0. Журналы тестирования записывают только сообщения, касающиеся определенных сбоев интерфейса IFilter. Тест выводит содержимое сегмента.
  • 1. Тест регистрирует сообщения предупреждения, а также сообщения уровня 0.
  • 2 - Сообщения журналов тестов, касающиеся тестов, пройденных, а также сообщений уровня 1.
  • 3 — Тест регистрирует информационные сообщения, а также сообщения уровня 2. Кроме того, тест выгружает структуру фрагмента.
/t целое число Количество потоков для запуска. Значение по умолчанию — 1.
/r целое число] Рекурсивно фильтрует подкаталоги. Необязательный целочисленный параметр указывает глубину, к которой необходимо выполнить рекурсию. Если целое число не указано или если целое число равно 0, предполагается полное рекурсионирование. По умолчанию глубина рекурсии составляет 1.
/c целое число Количество повторений цикла. Если целое число равно 0, тестовый цикл бесконечно. По умолчанию тестовый цикл выполняется только один раз.

Заметка

Необходимо включить пробел между параметром командной строки и значением.

filtdump.exe

Программа filtdump.exe загружает обработчик фильтра для указанного документа и выводит выходные данные, созданные библиотекой DLL IFilter. В следующем примере показано, как вызвать программу filtdump.exe.

filtdump filename.ext

Filtdump.exe использует метод ILoadFilter::LoadIFilter для загрузки библиотеки DLL IFilter, соответствующей указанному расширению имени файла, и выводит результаты. Например, следующая команда указывает filtdump.exe загрузить обработчик фильтра smpfilt.dll для расширения SMP, извлечь весь текст и свойства из файла 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 принимает следующие четыре параметра:

  1. grfFlags
  2. cAttributes
  3. атрибуты
  4. pdwFlags

Пользователь программы ifilttst.exe набора тестов IFilter может указать значения этих параметров в файле с именем ifilttst.ini. В следующей таблице описываются записи в файле ifilttst.ini, указывающие первые три параметра (входные параметры). Пример файла см. в разделе Пример ifilttst.ini файла.

Заметка

Нет записи таблицы для параметра pdwFlags, так как это выходной параметр; Перед вызовом метода IFilter::Init не требуется никакое специальное значение.

  Вход Описание
Флаги Имена флагов IFILTER_INIT, которые должны быть присоединены оператором OR для формирования параметра grfFlags метода IFilter::Init. Имена флагов должны быть в верхнем регистре и в одной строке.
cAttributes Десятичное целое число, представляющее значение параметра cAttributes.
"атрибуты" Эта запись должна начинаться с aAttributes и должна отличаться от других aAttributes записей в разделе. Юридические названия для записи aAttributes следующие: aAttributes, aAttributes1, aAttributes2и так далее. Первый токен должен быть GUID. GUID должен быть отформатирован точно так, как показано в разделе [Test3]примера файла ifilttst.ini. Второй маркер может быть идентификатором свойства (PID), состоящим из числа в шестнадцатеричной нотации, или указателем на широкую символьную строку (lpwstr). Lpwstr можно указать, заключив строку в двойные кавычки, как показано в разделе [Test6] примера файла ifilttst.ini.

Если флаги и 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 должны быть уникальными и увеличиваться.
  • STAT_CHUNK. Параметрфлаги является распознаваемым состоянием сегмента, например 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.

Проверка согласованности проверяет следующие условия:

  • Каждая STAT_CHUNK структура, возвращаемая методом IFilter::GetChunk, идентична соответствующей 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 и повторно привязывает, на этот раз инициализируя его со следующим набором параметров. Тест повторяет цикл: тест валидации, проверка согласованности и тест на недопустимый ввод, пока не будут проверены все необходимые конфигурации IFilter, указанные в файле ifilttst.ini.

Обеспечение индексации зарегистрированных элементов

Окончательный тест вашего IFilter гарантирует, что ваш IFilter правильно зарегистрирован и вызывается для индексирования элементов, которые вы зарегистрировали для его использования. Вы можете использовать Диспетчер каталогов для начала повторного индексирования или воспользоваться Диспетчером областей обхода (CSM) для настройки правил по умолчанию, указывающих URL-адреса, которые должен обходить индексатор. После завершения индексирования используйте пользовательский интерфейс поиска Windows для поиска строки в содержимом или свойствах элементов. Если элементы были индексированы, они будут отображаться в результатах поиска.

Дополнительные сведения о повторном индексировании см. в разделе Использование диспетчера каталогов и с помощью диспетчера областей обхода. Пример кода RedexMatchingUrls демонстрирует способы указания файлов для повторного индексирования и способа. В примере кода 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 вызвал блок с идентификатором процесса 0x5. Проверка раздела [Test1] в ifilttst.ini покажет, что IFilter был сконфигурирован так, чтобы не эмитировать блоки с этим PID. Например, если ни IFILTER_INIT_APPLY_INDEX_ATTRIBUTES, ни IFILTER_INIT_APPLY_OTHER_ATTRIBUTES не указаны в поле Flags, и если cAttributes равны 0, то IFilter выдает только блоки с идентификатором 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, соответствующий HTML IFilter, и другой идентификатор PID, соответствующий HTML HREF. Это внутреннее свойство типа значения, экспортируемое компонентом HTML IFilter.

Следующий блок, начиная с строки 21, имеет тот же GUID и PID, но его состояние блока VALUE вместо TEXT. Обратите внимание, что текст в этих последних двух блоках совпадает с первым блоком. Но поскольку IFilter предназначен для трёх атрибутов (обычный текст, HTML HREF как текст и HTML HREF как значение), которые применяются к этой фразе, результаты выводятся в трёх отдельных блоках.

Дополнительные ресурсы

разработка обработчиков фильтров

Об обработчиках фильтров в Поиске Windows

Рекомендации по созданию обработчиков фильтров в Поиске Windows

возврат свойств из обработчика фильтров

Обработчики фильтров , которые поставляются с Windows

Реализация обработчиков фильтров в поисковой системе Windows

Регистрация обработчиков фильтров