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

Набор тестов 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 integer] Рекурсивно фильтрует подкаталоги. Необязательный целочисленный параметр указывает глубину для выполнения рекурсии. Если целое число не указано или целое число равно 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 перечисляет все расширения имен файлов, с которыми связаны обработчики фильтров, путем печати расширения имени файла и имени библиотеки DLL IFilter для расширения. Это простой способ проверить правильность установки IFilter.

ifilttst.ini

Интерфейс IFilter инициализируется путем вызова метода IFilter::Init . Метод IFilter::Init принимает следующие четыре параметра:

  1. grfFlags
  2. cAttributes
  3. aAttributes
  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 : aAttributes, aAttributes1, aAttributes2 и т. д. Первым маркером должен быть GUID. Guid должен быть отформатирован точно так, как показано в [Test3] разделе Примера файла ifilttst.ini. Второй маркер может быть либо идентификатором свойства (PID), состоящим из числа в шестнадцатеричной нотации, либо указателем на широкую символьную строку (lpwstr). Lpwstr можно указать, заключив строку в двойные кавычки, как показано в [Test6] разделе Примера файла ifilttst.ini.

Если записи 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 должны быть уникальными и увеличиваться.
  • 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_INDEXING_ONLY IFILTER_INIT , тест освобождает интерфейс 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 Search для поиска строки в содержимом или свойствах элементов. Если элементы были проиндексированы, они будут отображаться в результатах поиска.

Дополнительные сведения о повторном индексировании см. в разделах Использование диспетчера каталогов и Использование диспетчера области обхода контента. В примере кода 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. Проверка раздела [Test1] в ifilttst.ini покажет, что 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, соответствующий HTML IFilter, и другой ИДЕНТИФИКАТОР, соответствующий HTML HREF. Это внутреннее свойство типа значения, экспортируемое HTML IFilter.

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

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

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

Сведения об обработчиках фильтров в Windows Search

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

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

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

Реализация обработчиков фильтров в Windows Search

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