Share via


Test dei gestori di filtri

La suite di test IFilter convalida i gestori di filtri. La suite di test esegue questa operazione chiamando i metodi IFilter e controllando i valori restituiti per la conformità con la specifica dell'interfaccia IFilter ; e verifica che gli identificatori di blocchi siano univoci e crescenti, che l'interfaccia IFilter si comporta in modo coerente dopo la ri-inizializzazione e che qualsiasi metodo IFilter chiama con parametri non validi restituisce i codici di errore previsti. I programmi della suite di test scaricano anche l'output di un file filtrato da un gestore di filtri e controllano le informazioni di registrazione IFilter nel Registro di sistema.

Questo argomento è organizzato come segue:

Nota

Se un nuovo gestore di filtro per un tipo di file viene installato come sostituzione di una registrazione di filtro esistente, il programma di installazione deve salvare la registrazione corrente e ripristinarlo se il nuovo gestore del filtro viene disinstallato. Non esiste alcun meccanismo per concatenare i filtri. Di conseguenza, il nuovo gestore di filtri è responsabile della replica di qualsiasi funzionalità necessaria del filtro precedente.

Command-Line chiamata

La suite di test IFilter è costituita da tre applicazioni da riga di comando: ifilttst.exe,filtdump.exe e filtreg.exee un file di inizializzazione, ifilttst.ini.

Importante

In Windows 7 e versioni successive i filtri scritti nel codice gestito vengono bloccati in modo esplicito. I filtri DEVONO essere scritti nel codice nativo a causa di potenziali problemi di versioni CLR (Common Language Runtime) con il processo in cui vengono eseguiti più componenti aggiuntivi.

ifilttst.exe

Il programma ifilttst.exe esegue diversi test per convalidare un gestore di filtri. Nell'esempio seguente viene illustrato come richiamare il programma ifilttst.exe dalla riga di comando:

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

Nell'esempio vengono eseguite le attività seguenti:

  • Indirizza il programma per filtrare il file test.htm
  • Reindirizza i messaggi di log a test.htm.log
  • Reindirizza i messaggi di dump a test.htm.dmp
  • Imposta la verbosità su 1

Per il funzionamento del comando precedente, tre file devono trovarsi nella directory di lavoro corrente: test.htm, ifilttst.exee ifilttst.ini. Le opzioni della riga di comando sono elencate nella tabella seguente.

Cambiare e possibili variabili Descrizione
/i nome file File di input o directory da filtrare. Il nome del file può contenere i caratteri * jolly e ?.
/L I messaggi di log vengono indirizzati a un file anziché alla schermata. I messaggi di log descrivono i singoli test eseguiti e i risultati superati/non riusciti dei test. Il nome del file di log è lo stesso del nome del file di input, ma con estensione log.
/d I messaggi di dump vengono indirizzati a un file anziché alla schermata. I messaggi di dump descrivono il contenuto dei blocchi. La struttura del blocco viene scaricata quando il livello di verbosità è 3. Il nome del file dump è lo stesso del nome del file di input, ma con estensione dmp.
/-L Disabilitare la registrazione. Questo flag esegue l'override dell'opzione /l .
/-D Disabilitare il dump. Questo flag esegue l'override dell'opzione /d .
/v integer Livello di dettaglio. Il valore predefinito è 3.
  • 0 : registra solo i messaggi relativi a errori specifici dell'interfaccia IFilter . Il test esegue il dump del contenuto del blocco.
  • 1 : i messaggi di avviso dei log di test e quelli per il livello 0.
  • 2 : i messaggi di test riguardano i test passati e quelli per il livello 1.
  • 3 : i messaggi informativi dei log di test e quelli per il livello 2. Inoltre, il test esegue il dump della struttura del blocco.
/t integer Numero di thread da avviare. Il valore predefinito è 1.
/r integer] Filtra in modo ricorsivo le sottodirectory. Il parametro integer facoltativo specifica la profondità a cui eseguire la ricorsione. Se non viene specificato alcun intero o se l'intero è 0, viene presupposta la ricorsione completa. Per impostazione predefinita, la profondità di ricorsione è 1.
/c integer Numero di volte in cui eseguire il ciclo. Se l'intero è 0, il ciclo di test viene eseguito in modo infinito. Per impostazione predefinita, il ciclo di test viene eseguito una sola volta.

Nota

È necessario includere uno spazio tra l'opzione della riga di comando e il valore.

filtdump.exe

Il programma filtdump.exe carica un gestore di filtri per un documento specificato e stampa l'output prodotto dalla DLL IFilter . Nell'esempio seguente viene illustrato come richiamare il programma di filtdump.exe.

filtdump filename.ext

Filtdump.exe usa il metodo ILoadFilter::LoadIFilter per caricare la DLL IFilter appropriata per l'estensione del nome file specificata e stampa i risultati. Ad esempio, il comando seguente indica filtdump.exe di caricare il gestore di filtri smpfilt.dll per l'estensione smp, estrarre tutto il testo e le proprietà dal file myfile.smp e stampare i risultati.

filtdump myfile.smp

filtreg.exe

Il programma filtreg.exe controlla le informazioni di installazione di IFilter nel Registro di sistema. Si richiama il programma filtreg.exe dalla riga di comando digitando il nome, come nell'esempio seguente.

filtreg

Filtreg.exe enumera tutte le estensioni di nome file associate ai gestori di filtri stampando l'estensione del nome file e il nome della DLL IFilter per l'estensione. Si tratta di un modo semplice per verificare l'installazione corretta di un IFilter.

ifilttst.ini

Un'interfaccia IFilter viene inizializzata chiamando il metodo IFilter::Init . Il metodo IFilter::Init accetta i quattro parametri seguenti:

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

L'utente del programma di ifilttst.exe del gruppo di test IFilter può specificare i valori per questi parametri in un file denominato ifilttst.ini. Nella tabella seguente vengono descritte le voci del file ifilttst.ini che specificano i primi tre parametri (i parametri di input). Per un file di esempio, vedere File di esempio ifilttst.ini.

Nota

Non esiste alcuna voce di tabella per il parametro pdwFlags perché è un parametro di output; non deve avere alcun valore speciale prima della chiamata al metodo IFilter::Init .

  Voce Descrizione
Flags Nomi dei flag IFILTER_INIT che devono essere uniti dall'operatore OR per formare il parametro grfFlags del metodo IFilter::Init . I nomi dei flag devono essere tutti maiuscoli e nella stessa riga.
cAttributes Intero decimale che rappresenta il valore del parametro cAttributes .
aAttributes Questa voce deve iniziare con aAttributes e deve essere diversa dalle altre voci di aAttributes all'interno della sezione. I nomi legali per la voce aAttributes sono: aAttributes, aAttributes1, aAttributes2 e così via. Il primo token deve essere un GUID. Il GUID deve essere formattato esattamente come illustrato nella [Test3] sezione del file di esempio ifilttst.ini. Il secondo token può essere un identificatore di proprietà (PID) costituito da un numero in notazione esadecimale o un puntatore a una stringa di caratteri wide (lpwstr). È possibile specificare un lpwstr racchiudendo la stringa tra virgolette doppie, come illustrato nella [Test6] sezione del file di esempio ifilttst.ini.

Se le voci Flag e cAttributes non sono specificate, per impostazione predefinita è 0. Se si imposta cAttributes uguale a 2, è necessario specificare due nomi aAttributes . [Test5] Nella sezione dell'esempio cAttributes è 1, ma non è stato specificato aAttributes. Il test chiama quindi il metodo IFilter::Init con cAttributes uguale a 1 e aAttributes uguale a NULL. Si tratta di un test case utile perché è probabile che causi una violazione di accesso nel metodo IFilter::Init .

Se ifilttst.exe non riesce a trovare un file denominato ifilttst.ini nella directory di lavoro, viene usata una configurazione predefinita per inizializzare l'oggetto IFilter::Init . Nell'esempio seguente viene illustrata la configurazione predefinita.

[default]
            grfFlags = IFILTER_INIT_APPLY_INDEX_ATTRIBUTES
            cAttributes = 0

File di ifilttst.ini di esempio

Il file ifilttst.ini è organizzato in sezioni, con il nome della sezione racchiuso tra parentesi quadre. Nell'esempio le sezioni sono denominate [Test1], [Test2]e così via. Tutti i nomi di sezione devono essere univoci. Il test legge i valori della prima sezione e inizializza IFilter con tali valori. Tutti i test vengono quindi eseguiti usando questa configurazione IFilter . Il filtro IFilter viene quindi rilasciato e reinizializzato, usando i parametri elencati in precedenza. Il processo viene ripetuto fino a quando non vengono testate tutte le configurazioni.

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

Procedura di test IFilter

Dopo l'inizializzazione di IFilter , il programma ifilttst.exe esegue una serie di test sul filtro IFilter. Oltre a seguire le procedure di test IFilter , assicurarsi che l'implementazione di IFilter usi procedure di codice sicure. Vedere "Secure Code Practices for Windows Search" (Procedure di protezione del codice per Windows Search) in Implementazione di gestori di filtri in Windows Search.

Test di convalida

Il test di convalida esegue la procedura attraverso l'oggetto un blocco alla volta, verificando ogni singolo blocco e tutti i codici restituiti. Il test di convalida salva tutte le strutture STAT_CHUNK restituite in un elenco.

Il test di convalida verifica le condizioni seguenti:

  • STAT_CHUNK. Gli ID blocchi idChunk devono essere univoci e crescenti.
  • STAT_CHUNK.il parametro flags è uno stato di blocco riconosciuto, ad esempio CHUNKSTATE, CHUNK_TEXT o costanti CenabledHUNK_VALUE.
  • STAT_CHUNK.Il parametro breakType è un tipo di interruzione riconosciuto (0, 1, 2, 3, 4).
  • Se gli attributi di inizializzazione IFilter specificano che IFilter deve restituire solo blocchi contenenti proprietà di tipo valore interno, idChunkSource deve essere uguale a 0.
  • Se il blocco non è derivato, se non è una proprietà di tipo valore interno, STAT_CHUNK. idChunkSource deve essere uguale a STAT_CHUNK. idChunk.
  • IFilter::GetChunk restituisce S_OK o un altro valore restituito accettabile, ad esempio FILTER_E_END_OF_CHUNKS, FILTER_E_LINK_UNAVAILABLE e così via.
  • Se il blocco contiene testo, IFilter::GetText restituisce S_OK, FILTER_S_LAST_TEXT o FILTER_E_NO_MORE_TEXT.
  • Se IFilter::GetText restituisce FILTER_S_LAST_TEXT, la chiamata successiva a IFilter::GetText restituisce FILTER_E_NO_MORE_TEXT.
  • Se il blocco contiene un valore, IFilter::GetValue restituisce S_OK o FILTER_E_NO_MORE_VALUES.

Test di coerenza

Il programma ifilttxt.exe inizializza nuovamente l'interfaccia IFilter con gli stessi parametri del test di convalida ed esegue un test di coerenza. Se l'implementazione di IFilter è stata inizializzata con il flag IFILTER_INIT_INDEXING_ONLY IFILTER_INIT , il test rilascia l'interfaccia IFilter e lo associa nuovamente prima di effettuare un'altra chiamata al metodo IFilter::Init .

Il test di coerenza verifica le condizioni seguenti:

  • Ogni struttura STAT_CHUNK restituita dal metodo IFilter::GetChunk è identica alla STAT_CHUNK corrispondente restituita nel test di convalida.
  • IFilter::GetChunk restituisce S_OK o un altro valore restituito accettabile, ad esempio FILTER_E_END_OF_CHUNKS, FILTER_E_LINK_UNAVAILABLE e così via.

Test di input non valido

Il programma ifilttst.exe inizializza nuovamente l'interfaccia IFilter con gli stessi parametri ed esegue un test di input non valido. Questo test esegue il passaggio del documento un blocco alla volta che effettua chiamate di funzione in modo non corretto, ad esempio chiamando il metodo IFilter::GetValue quando il blocco corrente contiene testo. Il test verifica la conformità di tutti i codici restituiti alla specifica IFilter .

Il test di input non valido verifica le condizioni seguenti:

  • Se il blocco corrente contiene testo, IFilter::GetValue restituisce FILTER_E_NO_VALUES e una chiamata a IFilter::GetText ha esito positivo.
  • Se il blocco corrente contiene un valore, IFilter::GetText restituisce FILTER_E_NO_TEXT e una chiamata a IFilter::GetValue ha esito positivo.
  • Se la chiamata precedente a IFilter::GetText ha restituito FILTER_E_NO_MORE_TEXT, le chiamate successive a IFilter::GetText restituiscono FILTER_E_NO_MORE_TEXT.
  • Se la chiamata precedente a IFilter::GetValue ha restituito FILTER_E_NO_MORE_VALUES, le chiamate successive a IFilter::GetValue restituiscono FILTER_E_NO_MORE_VALUES.
  • Se la chiamata precedente a IFilter::GetChunk ha restituito FILTER_E_END_OF_CHUNKS, le chiamate successive a IFilter::GetChunk restituiscono FILTER_E_END_OF_CHUNKS.

Nota

Il test di input non valido confronta le strutture di blocco correnti con quelle restituite nel test di convalida per assicurarsi che siano identiche.

Test di configurazioni IFilter diverse

Il programma ifilttst.exe rilascia l'interfaccia IFilter e ribind, questa volta inizializzandola con il set successivo di parametri. Il test ripete il ciclo: test di convalida, test di coerenza e test di input non valido, fino a quando non sono state testate tutte le configurazioni IFilter desiderate specificate in ifilttst.ini file.

Verifica dell'indicizzazione degli elementi registrati

Il test finale del filtro IFilter garantisce che il filtro IFilter sia registrato correttamente e che venga richiamato per indicizzare gli elementi registrati per usarlo. È possibile usare Gestione cataloghi per avviare nuovamente l'indicizzazione o usare Gestione ambito ricerca per indicizzazione per configurare le regole predefinite che indicano gli URL di cui si vuole eseguire la ricerca per indicizzazione dall'indicizzatore. Al termine dell'indicizzazione, usare l'interfaccia utente di Windows Search per cercare una stringa nel contenuto o nelle proprietà degli elementi. Se gli elementi sono stati indicizzati, verranno visualizzati nei risultati della ricerca.

Per altre informazioni sulla reindicizzazione, vedere Uso di Gestione cataloghi e Utilizzo di Gestione ambito ricerca per indicizzazione. L'esempio di codice ReindexMatchingUrls illustra i modi per specificare quali file indicizzare e come eseguire nuovamente l'indicizzazione. L'esempio di codice CrawlScopeCommandLine illustra come definire le opzioni della riga di comando per le operazioni di indicizzazione di Crawl Scope Manager (CSM). Entrambi gli esempi di codice sono disponibili in GitHub.

File di log di esempio

Su richiesta, il programma Ifilttst.exe può produrre un log contenente una descrizione dei passaggi necessari durante l'esecuzione. Gli esempi seguenti sono estratti da un file di log, con il livello di dettaglio impostato sul valore massimo possibile 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 prima riga è un messaggio informativo che indica che una nuova configurazione è stata caricata dal file ifilttst.ini. La riga (3) indica il nome della sezione nel file ifilttst.ini da cui è stata letta la configurazione corrente. Le righe (da 4) a (7) elencano i parametri per IFilter::Init. Le righe che iniziano con INFO sono messaggi informativi sull'associazione di IFilter e sull'inizio del test di convalida. Le righe che iniziano con PASS sono messaggi relativi a test specifici superati.

La riga nell'esempio di log seguente è un avviso. Gli avvisi richiamano l'attenzione sul comportamento IFilter problematico, anche se legale. Questo avviso indica che il metodo IFilter::GetChunk ha restituito un blocco di testo che non contiene testo.

WARNING-First call to GetText() returned FILTER_E_NO_MORE_TEXT.

Il messaggio di errore di esempio seguente indica che IFilter ha generato un blocco non richiesto.

            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

Nel caso di questo messaggio di errore di esempio, il filtro IFilter ha generato un blocco con un PID di 0x5. L'ispezione della sezione [Test1] in ifilttst.ini mostra che il filtro IFilter è stato configurato per non generare blocchi con questo PID. Ad esempio, se né IFILTER_INIT_APPLY_INDEX_ATTRIBUTES né IFILTER_INIT_APPLY_OTHER_ATTRIBUTES sono stati specificati nella voce Flags e se cAttributes erano 0, IFilter genera solo blocchi con un PID di 0x13 e corrispondente a PID_STG_CONTENTS.

File dump di esempio

Su richiesta, il programma Ifilttst.exe può produrre un dump contenente i blocchi trovati e il relativo contenuto. L'esempio seguente è un estratto di un file di dump di questo tipo.

                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

Le prime nove righe descrivono la struttura corrente del blocco. Il GUID e il PID corrispondono a PSGUID_STORAGE/PID_STG_CONTENTS. Si tratta di un blocco contenente testo normale. Il testo si trova nella struttura del blocco seguente:

10. This is an HTML IFilter test page

Il blocco successivo, a partire dalla riga 11, ha un GUID diverso, corrispondente a e un PID diverso, corrispondente a HTML IFilterun HREF HTML. Si tratta di una proprietà di tipo valore interno, esportata da HTML IFilter.

Il blocco successivo, a partire dalla riga 21, ha lo stesso GUID e PID, ma il relativo stato di blocco è VALUE invece di TEXT. Si noti che il testo di questi ultimi due blocchi è lo stesso del primo blocco. Tuttavia, poiché IFilter è progettato per tre attributi (testo normale, HTML HREF come testo e HTML HREF come valore) da applicare a questa frase, i risultati vengono generati in tre blocchi separati.

Risorse aggiuntive

Sviluppo di gestori di filtri

Informazioni sui gestori di filtri in Windows Search

Procedure consigliate per la creazione di gestori di filtri in Windows Search

Restituzione di proprietà da un gestore di filtri

Gestori di filtri che vengono forniti con Windows

Implementazione dei gestori di filtri in Windows Search

Registrazione dei gestori di filtri