Test des gestionnaires de filtres

La suite de tests IFilter valide vos gestionnaires de filtres. La suite de tests le fait en appelant les méthodes IFilter et en vérifiant les valeurs retournées pour la conformité avec la spécification de l’interface IFilter ; et vérifier que les identificateurs de segment sont uniques et croissants, que l’interface IFilter se comporte de manière cohérente après la réinitialisation, et que les appels de méthode IFilter avec des paramètres non valides retournent des codes d’erreur attendus. Les programmes de suite de tests vident également la sortie d’un fichier filtré par un gestionnaire de filtres et vérifient les informations d’inscription IFilter dans le Registre.

Cette rubrique est organisée comme suit :

Note

Si un nouveau gestionnaire de filtres pour un type de fichier est installé en remplacement d’une inscription de filtre existante, le programme d’installation doit enregistrer l’inscription actuelle et le restaurer si le nouveau gestionnaire de filtres est désinstallé. Il n’existe aucun mécanisme permettant de chaîner des filtres. Par conséquent, le nouveau gestionnaire de filtres est chargé de répliquer toutes les fonctionnalités nécessaires de l’ancien filtre.

Appel de ligne de commande

La suite de tests IFilter se compose de trois applications en ligne de commande : ifilttst.exe, filtdump.exeet filtreg.exe et un fichier d’initialisation, ifilttst.ini.

Important

Dans Windows 7 et versions ultérieures, les filtres écrits dans le code managé sont explicitement bloqués. Les filtres DOIVENT être écrits en code natif en raison de problèmes potentiels de contrôle de version avec le Common Language Runtime (CLR) et le processus où plusieurs compléments s'exécutent.

Ifilttst.exe

Le programme ifilttst.exe exécute plusieurs tests pour valider un gestionnaire de filtres. L’exemple suivant montre comment appeler le programme ifilttst.exe à partir de la ligne de commande :

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

L’exemple effectue les tâches suivantes :

  • Dirige le programme pour filtrer le fichier test.htm
  • Redirige les messages de journal vers test.htm.log
  • Redirige les messages de déchargement vers test.htm.dmp
  • Définit la verbosité à 1

Pour que la commande précédente fonctionne, trois fichiers doivent se trouver dans le répertoire de travail actuel : test.htm, ifilttst.exeet ifilttst.ini. Les commutateurs de ligne de commande sont répertoriés dans le tableau suivant.

Changer et variables possibles Descriptif
/i nom de fichier Fichier ou répertoire d’entrée à filtrer. Le nom de fichier peut contenir les caractères * génériques et ?.
/l Les messages de journal sont dirigés vers un fichier au lieu de l’écran. Les messages de journal décrivent les tests individuels effectués et les résultats de réussite/échec des tests. Le nom du fichier journal est identique au nom du fichier d’entrée, mais avec une extension .log.
/d Les messages de vidage sont dirigés vers un fichier au lieu de l’écran. Les messages de vidage décrivent le contenu des blocs. La structure de blocs est vidée lorsque le niveau de détail est 3. Le nom du fichier de vidage est identique au nom du fichier d’entrée, mais avec une extension .dmp.
/-l Désactivez la journalisation. Cet indicateur remplace l'option /l.
/-d Désactivez le vidage. Cet indicateur remplace le paramètre /d.
/v entier Niveau de verbosité. La valeur par défaut est 3.
  • 0 - Le test journalise uniquement les messages concernant des échecs d’interface IFilter spécifiques. Le test vide le contenu du bloc.
  • 1 - Le test enregistre les messages d’avertissement ainsi que ceux du niveau 0.
  • 2 - Le test consigne les messages concernant les tests qui ont réussi ainsi que ceux du niveau 1.
  • 3 - Le test consigne les messages d’information ainsi que ceux du niveau 2. En outre, le test vide la structure du bloc.
/t entier Nombre de threads à lancer. La valeur par défaut est 1.
/r integer] Filtre de manière récursive les sous-répertoires. Le paramètre entier facultatif spécifie la profondeur à laquelle effectuer l’exercice de la récursivité. Si aucun entier n’est spécifié ou si l’entier est égal à 0, la récursivité complète est supposée. Par défaut, la profondeur de récursivité est 1.
Entier /c Nombre de répétitions. Si l’entier est 0, les boucles de test sont infinies. Par défaut, la boucle de test ne boucle qu'une seule fois.

Note

Vous devez inclure un espace entre le commutateur de ligne de commande et la valeur.

Filtdump.exe

Le programme filtdump.exe charge un gestionnaire de filtres pour un document spécifié et imprime la sortie produite par la DLL IFilter . L’exemple suivant montre comment appeler le programme filtdump.exe.

filtdump filename.ext

Filtdump.exe utilise la méthode ILoadFilter ::LoadIFilter pour charger la DLL IFilter appropriée pour l’extension de nom de fichier spécifiée et imprime les résultats. Par exemple, la commande suivante indique filtdump.exe de charger le gestionnaire de filtres smpfilt.dll pour l’extension .smp, d’extraire tout le texte et les propriétés du fichier myfile.smp et d’imprimer les résultats.

filtdump myfile.smp

Filtreg.exe

Le programme filtreg.exe inspecte les informations d’installation de IFilter dans le Registre. Vous appelez le programme filtreg.exe à partir de la ligne de commande en tapant son nom, comme dans l’exemple suivant.

filtreg

Filtreg.exe énumère toutes les extensions de nom de fichier associées à des gestionnaires de filtres en imprimant l’extension de nom de fichier et le nom de la DLL IFilter pour l’extension. Il s’agit d’un moyen simple de vérifier l’installation correcte d’un IFilter.

Ifilttst.ini

Une interface IFilter est initialisée en appelant la méthode IFilter ::Init . La méthode IFilter ::Init accepte les quatre paramètres suivants :

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

L’utilisateur du programme ifilttst.exe de la suite de tests IFilter peut spécifier les valeurs de ces paramètres dans un fichier appelé ifilttst.ini. Le tableau suivant décrit les entrées du fichier ifilttst.ini qui spécifient les trois premiers paramètres (les paramètres d’entrée). Pour obtenir un exemple de fichier, consultez Exemple de fichier ifilttst.ini.

Note

Il n’existe aucune entrée de table pour le paramètre pdwFlags , car il s’agit d’un paramètre de sortie ; il n’est pas nécessaire d’avoir une valeur spéciale avant l’appel à la méthode IFilter ::Init .

  Entrée Descriptif
Flags Noms des indicateurs IFILTER_INIT qui doivent être joints par l’opérateur OR pour former le paramètre grfFlags de la méthode IFilter ::Init . Les désignations de drapeaux doivent toutes être en majuscules et sur la même ligne.
cAttributes Entier décimal représentant la valeur du paramètre cAttributes .
aAttributes Cette entrée doit commencer par aAttributes et doit être différente des autres entrées aAttributes dans la section. Les noms légaux de l’entrée aAttributes sont : aAttributes, aAttributes1,aAttributes2, etc. Le premier jeton doit être un GUID. Le GUID doit être mis en forme exactement comme illustré dans la [Test3] section de l’exemple de fichier ifilttst.ini. Le deuxième jeton peut être un identificateur de propriété (PID) composé d’un nombre en notation hexadécimale ou d’un pointeur vers une chaîne de caractères large (lpwstr). Une lpwstr peut être spécifiée en plaçant la chaîne entre guillemets doubles, comme illustré dans la [Test6] section de l’exemple de fichier ifilttst.ini.

Si les entrées Flags et cAttributes ne sont pas spécifiées, elles sont par défaut 0. Si vous définissez cAttributes sur 2, vous devez spécifier deux noms aAttributes . Dans la [Test5] section de l’exemple, cAttributes est 1, mais aucun aAttributes n’a été spécifié. Le test appelle ensuite la méthode IFilter ::Init avec cAttributes égales à 1 et aAttributes égales à NULL. Il s’agit d’un cas de test utile, car il est susceptible d’entraîner une violation d’accès dans la méthode IFilter ::Init .

Si ifilttst.exe ne trouve pas de fichier nommé ifilttst.ini dans le répertoire de travail, une configuration par défaut est utilisée pour initialiser l’objet IFilter ::Init . L’exemple suivant illustre la configuration par défaut.

[default]
            grfFlags = IFILTER_INIT_APPLY_INDEX_ATTRIBUTES
            cAttributes = 0

Exemple de fichier ifilttst.ini

Le fichier ifilttst.ini est organisé en sections, avec le nom de la section entre crochets. Dans l’exemple, les sections sont nommées [Test1], [Test2]et ainsi de suite. Tous les noms de section doivent être uniques. Le test lit les valeurs de la première section et initialise le IFilter avec ces valeurs. Ensuite, tous les tests sont exécutés à l’aide de cette configuration IFilter . Ensuite, le IFilter est libéré et réinitialisé, à l’aide de paramètres répertoriés ci-dessus. Le processus est répété jusqu’à ce que toutes les configurations soient testées.

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

Procédure de test IFilter

Une fois que le IFilter a été initialisé, le programme ifilttst.exe effectue une série de tests sur le IFilter. En plus de suivre les procédures de test IFilter , assurez-vous que votre implémentation IFilter utilise des pratiques de code sécurisées. Consultez « Pratiques de code sécurisées pour La recherche Windows » dans l’implémentation de gestionnaires de filtres dans Windows Search.

Test de validation

Le test de validation passe par l’objet un bloc à la fois, en vérifiant chaque bloc individuel et tous les codes de retour. Le test de validation enregistre toutes les structures de STAT_CHUNK retournées dans une liste.

Le test de validation vérifie les conditions suivantes :

  • Le STAT_CHUNK. les ID de segment idChunk doivent être uniques et croissants.
  • Le paramètre STAT_CHUNK.flags est un état de bloc reconnu, tel que les constantes CHUNKSTATE, CHUNK_TEXT ou CenabledHUNK_VALUE.
  • Le STAT_CHUNK. le paramètre breakType est un type d’arrêt reconnu (0, 1, 2, 3, 4).
  • Si les attributs d’initialisation IFilter spécifient que le IFilter doit retourner uniquement des blocs contenant des propriétés de type valeur interne, idChunkSource doit être égal à 0.
  • Si le bloc n’est pas dérivé autrement dit, s’il n’est pas une propriété de type valeur interne, STAT_CHUNK. idChunkSource doit être égal à STAT_CHUNK. idChunk.
  • IFilter ::GetChunk retourne S_OK ou d’autres valeurs de retour acceptables, telles que FILTER_E_END_OF_CHUNKS, FILTER_E_LINK_UNAVAILABLE, etc.
  • Si le bloc contient du texte, IFilter ::GetText retourne S_OK, FILTER_S_LAST_TEXT ou FILTER_E_NO_MORE_TEXT.
  • Si IFilter ::GetText retourne FILTER_S_LAST_TEXT, l’appel suivant à IFilter ::GetText retourne FILTER_E_NO_MORE_TEXT.
  • Si le bloc contient une valeur, IFilter ::GetValue retourne S_OK ou FILTER_E_NO_MORE_VALUES.

Test de cohérence

Le programme ifilttxt.exe initialise à nouveau l’interface IFilter avec les mêmes paramètres que dans le test de validation et effectue un test de cohérence. Si l’implémentation IFilter a été initialisée avec l’indicateur IFILTER_INIT IFILTER_INIT_INDEXING_ONLY , le test libère l’interface IFilter et le lie à nouveau avant d’effectuer un autre appel à la méthode IFilter ::Init .

Le test de cohérence vérifie les conditions suivantes :

  • Chaque structure STAT_CHUNK retournée par la méthode IFilter ::GetChunk est identique à la STAT_CHUNK correspondante retournée dans le test de validation.
  • IFilter ::GetChunk retourne S_OK ou d’autres valeurs de retour acceptables, telles que FILTER_E_END_OF_CHUNKS, FILTER_E_LINK_UNAVAILABLE, etc.

Test d’entrée non valide

Le programme ifilttst.exe initialise à nouveau l’interface IFilter avec les mêmes paramètres et effectue un test d’entrée non valide. Ce test parcourt le document un bloc à la fois en effectuant des appels de fonction de manière incorrecte, comme l'appel de la méthode IFilter::GetValue lorsque le bloc actuel contient du texte. Le test vérifie que tous les codes de retour sont conformes à la spécification IFilter .

Le test d’entrée non valide vérifie les conditions suivantes :

  • Si le bloc actuel contient du texte, IFilter ::GetValue retourne FILTER_E_NO_VALUES et un appel à IFilter ::GetText réussit.
  • Si le bloc actuel contient une valeur, IFilter ::GetText retourne FILTER_E_NO_TEXT et un appel à IFilter ::GetValue réussit.
  • Si l’appel précédent à IFilter ::GetText a retourné FILTER_E_NO_MORE_TEXT, les appels successifs à IFilter ::GetText retournent FILTER_E_NO_MORE_TEXT.
  • Si l’appel précédent à IFilter ::GetValue a retourné FILTER_E_NO_MORE_VALUES, les appels successifs à IFilter ::GetValue retournent FILTER_E_NO_MORE_VALUES.
  • Si l’appel précédent à IFilter ::GetChunk a retourné FILTER_E_END_OF_CHUNKS, les appels successifs à IFilter ::GetChunk retournent FILTER_E_END_OF_CHUNKS.

Note

Le test d’entrée non valide compare les structures de bloc actuelles à celles retournées dans le test de validation pour s’assurer qu’elles sont identiques.

Test de différentes configurations IFilter

Le programme ifilttst.exe libère l’interface IFilter puis la relie, cette fois l’initiant avec le jeu de paramètres suivant. Le test répète le cycle : test de validation, test de cohérence et test d’entrée non valide, jusqu’à ce que toutes les configurations IFilter souhaitées spécifiées dans ifilttst.ini fichier aient été testées.

S’assurer que les éléments inscrits sont indexés

Le test final de votre IFilter garantit que votre IFilter est correctement inscrit et qu’il est appelé pour indexer les éléments que vous avez inscrits pour l’utiliser. Vous pouvez utiliser le Gestionnaire de catalogue pour lancer la réindexation ou utiliser le Gestionnaire d’étendue d’analyse (CSM) pour configurer des règles par défaut indiquant les URL que vous souhaitez que l’indexeur analyse. Une fois l’indexation terminée, utilisez l’interface utilisateur de Recherche Windows pour rechercher une chaîne dans le contenu ou les propriétés des éléments. Si les éléments ont été indexés, ils apparaissent dans les résultats de la recherche.

Pour plus d’informations sur la réindexation, consultez Utilisation du Gestionnaire de catalogues et Utilisation du Gestionnaire d’étendue d’analyse. L’exemple de code ReindexMatchingUrls montre comment spécifier les fichiers à réindexer et comment procéder. L’exemple de code CrawlScopeCommandLine montre comment définir des options de ligne de commande pour les opérations d’indexation CSM (Crawl Scope Manager). Les deux exemples de code sont disponibles sur GitHub.

Exemple de fichier journal

À la demande, le programme Ifilttst.exe peut produire un journal contenant une description des étapes qu’il effectue pendant l’exécution. Les exemples suivants sont des extraits d’un fichier journal, avec le niveau de verbosité défini sur la valeur la plus élevée possible, soit 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.

La première ligne est un message d’information indiquant qu’une nouvelle configuration a été chargée à partir du fichier ifilttst.ini. La ligne (3) indique le nom de la section dans le fichier ifilttst.ini à partir duquel la configuration actuelle a été lue. Les lignes (4) à (7) répertorient les paramètres de IFilter::Init. Les lignes commençant par INFO sont des messages d’information sur la liaison du IFilter et le début du test de validation. Les lignes commençant par PASS sont des messages concernant des tests spécifiques qui ont réussi.

La ligne de l’exemple de journal suivant est un avertissement. Les avertissements appellent l’attention sur le comportement IFilter qui est problématique, bien que légal. Cet avertissement indique que la méthode IFilter ::GetChunk a renvoyé un bloc de texte qui ne contient aucun texte.

WARNING-First call to GetText() returned FILTER_E_NO_MORE_TEXT.

L’exemple de message d’erreur suivant indique que le IFilter a émis un bloc qui n’a pas été demandé.

            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

Dans le cas de cet exemple de message d’erreur, le IFilter a émis un bloc avec un PID de 0x5. L’inspection de la section [Test1] dans ifilttst.ini indique que le IFilter a été configuré pour ne pas émettre de blocs avec ce PID. Par exemple, si ni IFILTER_INIT_APPLY_INDEX_ATTRIBUTES ni IFILTER_INIT_APPLY_OTHER_ATTRIBUTES n’ont été spécifiés dans l’entrée Flags et si cAttributes étaient 0, IFilter émettrait uniquement des blocs avec un PID de 0x13 et correspondant à PID_STG_CONTENTS.

Exemple de fichier de débogage

À la demande, le programme Ifilttst.exe peut produire un vidage contenant les blocs qu’il trouve et leur contenu. L’exemple suivant est un extrait de ce fichier de vidage.

                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

Les neuf premières lignes décrivent la structure de bloc actuelle. Le GUID et le PID correspondent à PSGUID_STORAGE/PID_STG_CONTENTS. Il s’agit d’un bloc contenant du texte brut. Le texte se trouve dans la structure de bloc suivante :

10. This is an HTML IFilter test page

Le bloc suivant, commençant à la ligne 11, a un GUID différent, correspondant au HTML IFilter, et un autre PID, correspondant à un HREF HTML. Il s’agit d’une propriété de type valeur interne, exportée par le HTML IFilter.

Le bloc suivant, commençant à la ligne 21, a le même GUID et PID, mais son état de segment est VALUE au lieu de TEXT. Notez que le texte de ces deux derniers blocs est le même que pour le premier bloc. Toutefois, étant donné que le IFilter est conçu pour trois attributs (texte brut, HREF HTML en tant que texte et HREF HTML comme valeur) à appliquer à cette expression, les résultats sont émis dans trois blocs distincts.

Ressources supplémentaires

Développement de gestionnaires de filtres

À propos des gestionnaires de filtres dans Windows Search

Meilleures pratiques pour la création de gestionnaires de filtres dans Windows Search

Retour de propriétés à partir d’un gestionnaire de filtres

Gestionnaires de filtres fournis avec Windows

Implémentation de gestionnaires de filtres dans Windows Search

Inscription de gestionnaires de filtres