Compartir a través de


Probar controladores de filtro

El conjunto de pruebas de IFilter valida los controladores de filtro. El conjunto de pruebas lo hace llamando a métodos IFilter y comprobando los valores devueltos para cumplir con la especificación de la interfaz IFilter ; y comprobar que los identificadores de fragmento son únicos y aumentan, que la interfaz IFilter se comporta de forma coherente después de volver a inicializarse y que cualquier método IFilter llama a con parámetros no válidos devuelve códigos de error esperados. Los programas del conjunto de pruebas también vuelcan la salida de un archivo filtrado por un controlador de filtros y comprueban la información de registro de IFilter en el registro.

Este tema se organiza de la siguiente manera:

Nota

Si se instala un nuevo controlador de filtro para un tipo de archivo como reemplazo de un registro de filtro existente, el instalador debe guardar el registro actual y restaurarlo si se desinstala el nuevo controlador de filtros. No hay ningún mecanismo para encadenar filtros. Por lo tanto, el nuevo controlador de filtros es responsable de replicar cualquier funcionalidad necesaria del filtro anterior.

Invocación de Command-Line

El conjunto de pruebas de IFilter consta de tres aplicaciones de línea de comandos: ifilttst.exe, filtdump.exey filtreg.exe y un archivo de inicialización, ifilttst.ini.

Importante

En Windows 7 y versiones posteriores, los filtros escritos en código administrado se bloquean explícitamente. Los filtros deben escribirse en código nativo debido a posibles problemas de control de versiones de Common Language Runtime (CLR) con el proceso en el que se ejecutan varios complementos.

ifilttst.exe

El programa ifilttst.exe ejecuta varias pruebas para validar un controlador de filtros. En el ejemplo siguiente se muestra cómo invocar el programa ifilttst.exe desde la línea de comandos:

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

En el ejemplo se realizan las siguientes tareas:

  • Dirige al programa para filtrar el archivo test.htm
  • Redirige los mensajes de registro a test.htm.log.
  • Redirige los mensajes de volcado de memoria a test.htm.dmp.
  • Establece el nivel de detalle en 1

Para que el comando anterior funcione, deben encontrarse tres archivos en el directorio de trabajo actual: test.htm, ifilttst.exey ifilttst.ini. Los modificadores de línea de comandos se muestran en la tabla siguiente.

Cambiar y posibles variables Descripción
Nombre de archivo /i Archivo o directorio de entrada que se va a filtrar. El nombre de archivo puede contener los caracteres * comodín y ?.
/l Los mensajes de registro se dirigen a un archivo en lugar de a la pantalla. Los mensajes de registro describen las pruebas individuales realizadas y los resultados de las pruebas superadas o erróneas. El nombre del archivo de registro es el mismo que el nombre del archivo de entrada, pero con una extensión .log.
/d Los mensajes de volcado se dirigen a un archivo en lugar de a la pantalla. Los mensajes de volcado de memoria describen el contenido de los fragmentos. La estructura de fragmentos se volca cuando el nivel de detalle es 3. El nombre del archivo de volcado de memoria es el mismo que el nombre del archivo de entrada, pero con una extensión .dmp.
/-L Deshabilite el registro. Esta marca invalida el /l modificador.
/-D Deshabilite el volcado. Esta marca invalida el /d modificador.
/v entero Nivel de detalle. El valor predeterminado es 3.
  • 0 : la prueba registra solo los mensajes relativos a errores específicos de la interfaz IFilter . La prueba volca el contenido del fragmento.
  • 1 - Los mensajes de advertencia de los registros de prueba, así como los de nivel 0.
  • 2 - La prueba registra los mensajes relativos a las pruebas superadas, así como a las del nivel 1.
  • 3 : la prueba registra mensajes informativos, así como los de nivel 2. Además, la prueba volca la estructura del fragmento.
/t entero Número de subprocesos que se van a iniciar. El valor predeterminado es 1.
/r integer] Filtra de forma recursiva los subdirectorios. El parámetro entero opcional especifica la profundidad a la que se va a ejercer la recursividad. Si no se especifica ningún entero o si el entero es 0, se asume la recursividad completa. De forma predeterminada, la profundidad de recursividad es 1.
/c entero Número de veces que se va a recorrer. Si el entero es 0, la prueba se repite infinitamente. De forma predeterminada, la prueba solo se repite una vez.

Nota

Debe incluir un espacio entre el modificador de línea de comandos y el valor .

filtdump.exe

El programa filtdump.exe carga un controlador de filtro para un documento especificado e imprime la salida generada por el archivo DLL de IFilter . En el ejemplo siguiente se muestra cómo invocar el programa filtdump.exe.

filtdump filename.ext

Filtdump.exe usa el método ILoadFilter::LoadIFilter para cargar el archivo DLL de IFilter adecuado para la extensión de nombre de archivo especificada e imprime los resultados. Por ejemplo, el siguiente comando indica a filtdump.exe que cargue el controlador de filtro smpfilt.dll para la extensión .smp, extraiga todo el texto y las propiedades del archivo myfile.smp e imprima los resultados.

filtdump myfile.smp

filtreg.exe

El programa filtreg.exe inspecciona la información de instalación de IFilter en el registro. Para invocar el programa filtreg.exe desde la línea de comandos, escriba su nombre, como en el ejemplo siguiente.

filtreg

Filtreg.exe enumera todas las extensiones de nombre de archivo que tienen controladores de filtro asociados mediante la impresión de la extensión de nombre de archivo y el nombre del archivo DLL de IFilter para la extensión. Se trata de una manera sencilla de comprobar la instalación correcta de un IFilter.

ifilttst.ini

Se inicializa una interfaz IFilter llamando al método IFilter::Init . El método IFilter::Init toma los cuatro parámetros siguientes:

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

El usuario del programa ifilttst.exe del conjunto de pruebas de IFilter puede especificar los valores de estos parámetros en un archivo denominado ifilttst.ini. En la tabla siguiente se describen las entradas del archivo ifilttst.ini que especifican los tres primeros parámetros (los parámetros de entrada). Para obtener un archivo de ejemplo, consulte Archivo de ejemplo ifilttst.ini.

Nota

No hay ninguna entrada de tabla para el parámetro pdwFlags porque es un parámetro de salida; no es necesario tener ningún valor especial antes de la llamada al método IFilter::Init .

  Entrada Descripción
Marcas Los nombres de las marcas de IFILTER_INIT que el operador OR va a unir para formar el parámetro grfFlags del método IFilter::Init . Los nombres de marca deben estar en mayúsculas y en la misma línea.
cAttributes Entero decimal que representa el valor del parámetro cAttributes .
aAttributes Esta entrada debe comenzar con aAttributes y debe ser diferente de las demás entradas aAttributes dentro de la sección. Los nombres legales de la entrada aAttributes son: aAttributes, aAttributes1, aAttributes2, etc. El primer token debe ser un GUID. El GUID debe tener el formato exacto como se muestra en la [Test3] sección del archivo de ejemplo ifilttst.ini. El segundo token puede ser un identificador de propiedad (PID) que consta de un número en notación hexadecimal o un puntero a una cadena de caracteres anchos (lpwstr). Se puede especificar un lpwstr mediante la inclusión de la cadena entre comillas dobles, como se muestra en la [Test6] sección del archivo de ejemplo ifilttst.ini.

Si no se especifican las entradas Flags y cAttributes , el valor predeterminado es 0. Si establece cAttributes igual a 2, debe especificar dos nombres aAttributes . En la [Test5] sección del ejemplo, cAttributes es 1, pero no se han especificado aAttributes . A continuación, la prueba llama al método IFilter::Init con cAttributes igual a 1 y aAttributes igual a NULL. Este es un caso de prueba útil porque es probable que cause una infracción de acceso en el método IFilter::Init .

Si ifilttst.exe no encuentra un archivo denominado ifilttst.ini en el directorio de trabajo, se usa una configuración predeterminada para inicializar el objeto IFilter::Init . En el ejemplo siguiente se muestra la configuración predeterminada.

[default]
            grfFlags = IFILTER_INIT_APPLY_INDEX_ATTRIBUTES
            cAttributes = 0

Archivo de ifilttst.ini de ejemplo

El archivo ifilttst.ini se organiza en secciones, con el nombre de sección entre corchetes. En el ejemplo, las secciones se denominan [Test1], [Test2], etc. Todos los nombres de sección deben ser únicos. La prueba lee los valores de la primera sección e inicializa el IFilter con esos valores. A continuación, todas las pruebas se ejecutan con esta configuración de IFilter . A continuación, el IFilter se libera y reinicializa, mediante parámetros enumerados anteriormente. El proceso se repite hasta que se prueban todas las configuraciones.

; 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"

Procedimiento de prueba de IFilter

Una vez inicializado el IFilter , el programa ifilttst.exe lleva a cabo una serie de pruebas en el IFilter. Además de seguir los procedimientos de prueba de IFilter , asegúrese de que la implementación de IFilter emplea prácticas de código seguras. Consulta "Prácticas de código seguro para Windows Search" en Implementar controladores de filtro en Windows Search.

Prueba de validación

La prueba de validación recorre el objeto un fragmento cada vez, comprobando cada fragmento individual y todos los códigos de retorno. La prueba de validación guarda todas las estructuras de STAT_CHUNK devueltas en una lista.

La prueba de validación comprueba las siguientes condiciones:

  • El STAT_CHUNK. Los identificadores de fragmentos idChunk deben ser únicos y aumentar.
  • El STAT_CHUNK. flags parameter es un estado de fragmento reconocido, como CHUNKSTATE, CHUNK_TEXT o constantes CenabledHUNK_VALUE.
  • El STAT_CHUNK. El parámetro breakType es un tipo de interrupción reconocido (0, 1, 2, 3, 4).
  • Si los atributos de inicialización de IFilter especifican que el IFilter debe devolver solo fragmentos que contengan propiedades internas de tipo valor, idChunkSource debe ser igual a 0.
  • Si el fragmento no se deriva, si no es una propiedad de tipo de valor interno, STAT_CHUNK. idChunkSource debe ser igual a STAT_CHUNK. idChunk.
  • IFilter::GetChunk devuelve S_OK u otro valor devuelto aceptable, como FILTER_E_END_OF_CHUNKS, FILTER_E_LINK_UNAVAILABLE, etc.
  • Si el fragmento contiene texto, IFilter::GetText devuelve S_OK, FILTER_S_LAST_TEXT o FILTER_E_NO_MORE_TEXT.
  • Si IFilter::GetText devuelve FILTER_S_LAST_TEXT, la siguiente llamada a IFilter::GetText devuelve FILTER_E_NO_MORE_TEXT.
  • Si el fragmento contiene un valor, IFilter::GetValue devuelve S_OK o FILTER_E_NO_MORE_VALUES.

Prueba de coherencia

El programa ifilttxt.exe vuelve a inicializar la interfaz IFilter con los mismos parámetros que en la prueba de validación y realiza una prueba de coherencia. Si la implementación de IFilter se ha inicializado con la marca IFILTER_INIT IFILTER_INIT_INDEXING_ONLY , la prueba libera la interfaz IFilter y la vuelve a enlazar antes de realizar otra llamada al método IFilter::Init .

La prueba de coherencia comprueba las siguientes condiciones:

  • Cada estructura STAT_CHUNK devuelta por el método IFilter::GetChunk es idéntica a la STAT_CHUNK correspondiente devuelta en la prueba de validación.
  • IFilter::GetChunk devuelve S_OK u otro valor devuelto aceptable, como FILTER_E_END_OF_CHUNKS, FILTER_E_LINK_UNAVAILABLE, etc.

Prueba de entrada no válida

El programa ifilttst.exe vuelve a inicializar la interfaz IFilter con los mismos parámetros y realiza una prueba de entrada no válida. Esta prueba recorre el documento un fragmento cada vez que se realizan llamadas de función incorrectamente, como llamar al método IFilter::GetValue cuando el chuck actual contiene texto. La prueba comprueba todos los códigos de retorno para el cumplimiento de la especificación IFilter .

La prueba de entrada no válida comprueba las siguientes condiciones:

  • Si el fragmento actual contiene texto, IFilter::GetValue devuelve FILTER_E_NO_VALUES y una llamada a IFilter::GetText se realiza correctamente.
  • Si el fragmento actual contiene un valor, IFilter::GetText devuelve FILTER_E_NO_TEXT y una llamada a IFilter::GetValue se realiza correctamente.
  • Si la llamada anterior a IFilter::GetText devolvió FILTER_E_NO_MORE_TEXT, las llamadas sucesivas a IFilter::GetText devuelven FILTER_E_NO_MORE_TEXT.
  • Si la llamada anterior a IFilter::GetValue devolvió FILTER_E_NO_MORE_VALUES, las llamadas sucesivas a IFilter::GetValue devuelven FILTER_E_NO_MORE_VALUES.
  • Si la llamada anterior a IFilter::GetChunk devolvió FILTER_E_END_OF_CHUNKS, las llamadas sucesivas a IFilter::GetChunk devuelven FILTER_E_END_OF_CHUNKS.

Nota

La prueba de entrada no válida compara las estructuras de fragmentos actuales con las devueltas en la prueba de validación para asegurarse de que son idénticas.

Probar diferentes configuraciones de IFilter

El programa ifilttst.exe libera la interfaz IFilter y vuelve a enlazarse, esta vez inicializándola con el siguiente conjunto de parámetros. La prueba repite el ciclo: prueba de validación, prueba de coherencia y prueba de entrada no válida, hasta que se hayan probado todas las configuraciones de IFilter deseadas especificadas en ifilttst.ini archivo.

Asegurarse de que los elementos registrados se indexan

La prueba final de su IFilter garantiza que su IFilter está registrado correctamente y que se invoca para indexar los elementos registrados para usarlos. Puede usar el Administrador de catálogos para iniciar la reindización o usar el Administrador de ámbitos de rastreo (CSM) para configurar reglas predeterminadas que indican las direcciones URL que desea que el indexador rastree. Una vez completada la indexación, use la interfaz de usuario de Windows Search para buscar una cadena en el contenido o las propiedades de los elementos. Si los elementos se indizaron, aparecerán en los resultados de la búsqueda.

Para obtener más información sobre cómo volver a indexar, vea Uso del Administrador de catálogos y Uso del Administrador de ámbitos de rastreo. En el ejemplo de código ReindexMatchingUrls se muestran formas de especificar qué archivos se van a volver a indexar y cómo. El ejemplo de código CrawlScopeCommandLine muestra cómo definir opciones de línea de comandos para las operaciones de indexación de Crawl Scope Manager (CSM). Ambos ejemplos de código están disponibles en GitHub.

Archivo de registro de ejemplo

A petición, el programa Ifilttst.exe puede generar un registro que contenga una descripción de los pasos que se llevan a cabo durante la ejecución. Los ejemplos siguientes son extractos de un archivo de registro, con el nivel de detalle establecido en el valor 3 más alto posible.

            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.

La primera línea es un mensaje informativo, que indica que se ha cargado una nueva configuración desde el archivo ifilttst.ini. Línea (3) indica el nombre de sección en el archivo ifilttst.ini desde el que se ha leído la configuración actual. Las líneas (4) a (7) enumeran los parámetros de IFilter::Init. Las líneas que comienzan por INFO son mensajes informativos sobre el enlace de IFilter y el inicio de la prueba de validación. Las líneas a partir de PASS son mensajes relacionados con pruebas específicas que se han superado.

La línea del ejemplo de registro siguiente es una advertencia. Las advertencias llaman la atención al comportamiento de IFilter que es problemático, aunque legal. Esta advertencia indica que el método IFilter::GetChunk ha devuelto un fragmento de texto que no contiene texto.

WARNING-First call to GetText() returned FILTER_E_NO_MORE_TEXT.

El siguiente mensaje de error de ejemplo indica que el IFilter emitió un fragmento que no se solicitó.

            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

En el caso de este mensaje de error de ejemplo, el IFilter emitió un fragmento con un PID de 0x5. La inspección de la sección [Test1] en ifilttst.ini mostraría que el IFilter estaba configurado para no emitir fragmentos con este PID. Por ejemplo, si ni IFILTER_INIT_APPLY_INDEX_ATTRIBUTES ni IFILTER_INIT_APPLY_OTHER_ATTRIBUTES se especificaron en la entrada Flags y si cAttributes fuera 0, IFilter emitiría solo fragmentos con un PID de 0x13 y correspondiente a PID_STG_CONTENTS.

Archivo de volcado de muestra

A petición, el programa Ifilttst.exe puede producir un volcado de memoria que contiene los fragmentos que encuentra y su contenido. En el ejemplo siguiente se muestra un extracto de este archivo de volcado de memoria.

                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

Las nueve primeras líneas describen la estructura de fragmentos actual. El GUID y el PID corresponden a PSGUID_STORAGE/PID_STG_CONTENTS. Se trata de un fragmento que contiene texto sin formato. El texto está en la siguiente estructura de fragmentos:

10. This is an HTML IFilter test page

El siguiente fragmento, a partir de la línea 11, tiene un GUID diferente, que corresponde a HTML IFiltery un PID diferente, que corresponde a un HREF HTML. Se trata de una propiedad de tipo de valor interno, exportada por .HTML IFilter

El siguiente fragmento, a partir de la línea 21, tiene el mismo GUID y PID, pero su estado de fragmento es VALUE en lugar de TEXT. Tenga en cuenta que el texto de estos dos últimos fragmentos es el mismo que para el primer fragmento. Pero dado que el IFilter está diseñado para tres atributos (texto sin formato, HTML HREF como texto y HTML HREF como valor) que se aplicarán a esta frase, los resultados se emiten en tres fragmentos independientes.

Recursos adicionales

Desarrollo de controladores de filtros

Acerca de los controladores de filtro en Windows Search

Procedimientos recomendados para crear controladores de filtro en Windows Search

Devolver propiedades de un controlador de filtros

Controladores de filtro que se envían con Windows

Implementación de controladores de filtro en Windows Search

Registro de controladores de filtro