Testowanie programów obsługi filtrów
Zestaw testów IFilter weryfikuje programy obsługi filtrów. Zestaw testów wykonuje następujące czynności: wywoływanie metod IFilter i sprawdzanie zwróconych wartości pod kątem zgodności ze specyfikacją interfejsu IFilter; i sprawdzanie, czy identyfikatory fragmentów są unikatowe i rosnące, że interfejs IFilter zachowuje się spójnie po ponownym zainicjowaniu oraz że każde wywołanie metod IFilter z nieprawidłowymi parametrami zwracają oczekiwane kody błędów. Programy zestawu testów również zrzucają wynik działania pliku filtrowanego przez moduł obsługi filtrów i sprawdzają informacje o rejestracji IFilter w rejestrze.
Ten temat jest zorganizowany w następujący sposób:
- Command-Line wywołanie
- procedura testowania IFilter
- zapewnienie indeksowania zarejestrowanych elementów
- dodatkowe zasoby
- Tematy pokrewne
Uwaga
Jeśli nowa procedura obsługi filtrów dla typu pliku jest instalowana jako zamiennik istniejącej rejestracji filtru, instalator powinien zapisać bieżącą rejestrację i przywrócić ją, jeśli zostanie odinstalowana nowa procedura obsługi filtrów. Nie ma mechanizmu tworzenia łańcuchów filtrów. W związku z tym nowa procedura obsługi filtrów jest odpowiedzialna za replikowanie wszelkich niezbędnych funkcji starego filtru.
wywołanie Command-Line
Pakiet testowy IFilter składa się z trzech aplikacji konsolowych: ifilttst.exe, filtdump.exei filtreg.exe oraz pliku inicjalizacji, ifilttst.ini.
Ważny
W systemie Windows 7 lub nowszym filtry napisane w kodzie zarządzanym są jawnie blokowane. Filtry MUSZĄ być zapisywane w kodzie natywnym z powodu potencjalnych problemów z wersją środowiska uruchomieniowego języka wspólnego (CLR) w procesie, w ramach którego działa wiele dodatków.
ifilttst.exe
Program ifilttst.exe uruchamia kilka testów w celu zweryfikowania programu obsługi filtrów. Poniższy przykład ilustruje sposób wywoływania programu ifilttst.exe z wiersza polecenia:
ifilttst /i test.htm /l /d /v 1
W przykładzie są wykonywane następujące zadania:
- Kieruje program do filtrowania pliku test.htm
- Przekierowuje komunikaty dziennika do test.htm.log
- Przekierowuje komunikaty zrzutu do test.htm.dmp
- Ustawia szczegółowość na 1
Aby poprzednie polecenie działało, w bieżącym katalogu roboczym muszą znajdować się trzy pliki: test.htm
, ifilttst.exei ifilttst.ini. Przełączniki wiersza polecenia są wymienione w poniższej tabeli.
Przełącznik i możliwe zmienne | Opis |
---|---|
/i nazwa pliku | Plik wejściowy lub katalog do filtrowania. Nazwa pliku może zawierać symbole wieloznaczne * i ? . |
/l | Komunikaty dziennika są kierowane do pliku zamiast ekranu. Komunikaty dziennika opisują wykonane poszczególne testy oraz wyniki powodzenia/niepowodzenia testów. Nazwa pliku dziennika jest taka sama jak nazwa pliku wejściowego, ale z rozszerzeniem .log. |
/d | Komunikaty zrzutu są kierowane do pliku zamiast ekranu. Komunikaty zrzutu opisują zawartość bloków danych. Struktura danych jest wyprowadzana, gdy poziom szczegółowości wynosi 3. Nazwa pliku zrzutu jest taka sama jak nazwa pliku wejściowego, ale z rozszerzeniem .dmp. |
/-l | Wyłącz rejestrowanie. Ta flaga zastępuje przełącznik /l . |
/-d | Wyłącz dumping. Ta flaga zastępuje przełącznik /d . |
/v liczba całkowita | Poziom szczegółowości. Wartość domyślna to 3.
|
/t liczba całkowita | Liczba wątków do uruchomienia. Wartość domyślna to 1. |
/r liczba całkowita] | Rekursywnie filtruje podkatalogi. Opcjonalny parametr liczby całkowitej określa głębokość, do której ma być wykonywane rekursja. Jeśli nie określono liczby całkowitej lub jeśli liczba całkowita wynosi 0, przyjmuje się, że przyjmuje się pełną rekursję. Domyślnie głębokość rekursji wynosi 1. |
/c liczba całkowita | Liczba powtórzeń pętli. Jeśli liczba całkowita wynosi 0, pętle testowe są nieskończonie. Domyślnie test wykonuje się w pętli tylko raz. |
Notatka
Musisz dołączyć spację między przełącznikiem wiersza polecenia a wartością.
filtdump.exe
Program filtdump.exe ładuje program obsługi filtrów dla określonego dokumentu i wyświetla dane wyjściowe wygenerowane przez bibliotekę DLL IFilter. Poniższy przykład ilustruje sposób wywoływania programu filtdump.exe.
filtdump filename.ext
Filtdump.exe używa metody ILoadFilter::LoadIFilter, aby załadować bibliotekę DLL IFilter odpowiednią dla określonego rozszerzenia nazwy pliku i wyświetla wyniki. Na przykład następujące polecenie powoduje, że filtdump.exe załadowuje obsługę filtrów smpfilt.dll dla rozszerzenia .smp, wyodrębnia wszystkie teksty i właściwości z pliku myfile.smp, a następnie drukuje wyniki.
filtdump myfile.smp
filtreg.exe
Program filtreg.exe sprawdza informacje o instalacji IFilter w rejestrze. Wywołasz program filtreg.exe z wiersza polecenia, wpisując jego nazwę, jak w poniższym przykładzie.
filtreg
Filtreg.exe wylicza wszystkie rozszerzenia nazw plików, które mają skojarzone z nimi programy obsługi filtrów, drukując rozszerzenie nazwy pliku i nazwę IFilter DLL rozszerzenia. Jest to prosty sposób weryfikacji prawidłowej instalacji IFilter.
ifilttst.ini
Interfejs IFilter jest inicjowany przez wywołanie metody IFilter::Init. Metoda IFilter::Init przyjmuje następujące cztery parametry:
- grfFlags
- cAttributes
- aAttributes
- pdwFlags
Użytkownik programu ifilttst.exe zestawu testów IFilter może określić wartości tych parametrów w pliku o nazwie ifilttst.ini. W poniższej tabeli opisano wpisy w pliku ifilttst.ini, które określają pierwsze trzy parametry (parametry wejściowe). Aby uzyskać przykładowy plik, zobacz Przykładowy plik ifilttst.ini Plik.
Notatka
Brak wpisu tabeli dla parametru pdwFlags, ponieważ jest to parametr wyjściowy; nie musi mieć żadnej specjalnej wartości przed wywołaniem metody IFilter::Init.
Wpis | Opis | |
---|---|---|
Flagi | Nazwy flag IFILTER_INIT, które mają być logicznie łączone przez operator OR w celu utworzenia parametru metody grfFlags dla IFilter::Init. Nazwy flag muszą mieć wielkie litery i w tym samym wierszu. | |
cAttributes | Liczba całkowita dziesiętna reprezentująca wartość parametru cAttributes. | |
aAttributes | Ten wpis musi zaczynać się od aAttributes i musi się różnić od innych aAttributes wpisów w sekcji. Prawidłowe nazwy dla wpisu aAttributes to: aAttributes, aAttributes1, aAttributes2, itd. Pierwszy token musi być identyfikatorem GUID. Identyfikator GUID musi być sformatowany dokładnie tak, jak pokazano w sekcji [Test3] pliku przykładowego ifilttst.ini. Drugi token może być identyfikatorem właściwości (PID) składającym się z liczby w notacji szesnastkowej lub wskaźnika do szerokiego ciągu znaków (lpwstr). Element lpwstr można określić, umieszczając ciąg w cudzysłowie podwójnym, jak pokazano w sekcji [Test6] pliku przykładowego ifilttst.ini. |
Jeśli pozycje Flags i cAttributes nie są określone, ich wartością domyślną jest 0. Jeśli ustawisz cAttributes równe 2, należy określić dwie aAttributes nazwy. W sekcji [Test5]
przykładu cAttributes wynosi 1, ale nie podano aAttributes. Następnie test wywołuje metodę IFilter::Init z cAttributes równe 1 i aAttributes równe NULL. Jest to przydatny przypadek testowy, ponieważ prawdopodobnie spowoduje naruszenie dostępu w metodzie IFilter::Init.
Jeśli ifilttst.exe nie można odnaleźć pliku o nazwie ifilttst.ini w katalogu roboczym, domyślna konfiguracja służy do inicjowania obiektu IFilter::Init. Poniższy przykład ilustruje konfigurację domyślną.
[default]
grfFlags = IFILTER_INIT_APPLY_INDEX_ATTRIBUTES
cAttributes = 0
Przykładowy plik ifilttst.ini
Plik ifilttst.ini jest zorganizowany w sekcjach z nazwą sekcji ujętą w nawiasy kwadratowe. W tym przykładzie sekcje mają nazwę [Test1]
, [Test2]
itd. Wszystkie nazwy sekcji muszą być unikatowe. Test odczytuje wartości z pierwszej sekcji i inicjuje IFilter z tymi wartościami. Następnie wszystkie testy są uruchamiane przy użyciu tej konfiguracji IFilter. Następnie IFilter jest zwalniany i ponownie inicjowany przy użyciu parametrów wymienionych powyżej. Proces jest powtarzany do momentu przetestowania wszystkich konfiguracji.
; 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 testowania IFilter
Po zainicjowaniu IFilter program ifilttst.exe przeprowadza serię testów na IFilter. Oprócz wykonywania procedur testowania IFilter upewnij się, że implementacja IFilter stosuje bezpieczne praktyki dotyczące kodu. Zobacz także "Secure Code Practices for Windows Search" (Praktyki bezpiecznego kodowania dla usługi Windows Search) w Implementacja obsługi filtrów w usłudze Windows Search.
Test weryfikacji
Test weryfikacji przechodzi przez jeden fragment obiektu naraz, weryfikując poszczególne fragmenty i wszystkie kody zwrotne. Test weryfikacyjny zapisuje wszystkie zwrócone struktury STAT_CHUNK na liście.
Test weryfikacji sprawdza następujące warunki:
- STAT_CHUNK.identyfikatory fragmentów muszą być unikatowe i rosnące.
- STAT_CHUNK.parametr flagi jest rozpoznawanym stanem fragmentu, takim jak CHUNKSTATE, CHUNK_TEXT lub stałe CenabledHUNK_VALUE.
- STAT_CHUNK.breakType parametr jest rozpoznawanym typem przerwania (0, 1, 2, 3, 4).
- Jeśli atrybuty inicjowania IFilter określają, że IFilter powinien zwracać tylko fragmenty zawierające właściwości typu wartości wewnętrznej, to idChunkSource musi być równe 0.
- Jeśli fragment nie pochodzi, to jeśli nie jest to wewnętrzna właściwość typu wartości, STAT_CHUNK.idChunkSource musi być równa STAT_CHUNK.idChunk.
- IFilter::GetChunk zwraca S_OK lub inną akceptowalną wartość zwracaną, taką jak FILTER_E_END_OF_CHUNKS, FILTER_E_LINK_UNAVAILABLE itd.
- Jeśli fragment zawiera tekst, IFilter::GetText zwraca S_OK, FILTER_S_LAST_TEXT lub FILTER_E_NO_MORE_TEXT.
- Jeśli IFilter::GetText zwróci FILTER_S_LAST_TEXT, następne wywołanie metody IFilter::GetText zwróci FILTER_E_NO_MORE_TEXT.
- Jeśli fragment zawiera wartość, IFilter::GetValue zwraca S_OK lub FILTER_E_NO_MORE_VALUES.
Test spójności
Program ifilttxt.exe ponownie inicjuje interfejs IFilter z tymi samymi parametrami co w teście weryfikacji i wykonuje test spójności. Jeśli implementacja IFilter została zainicjowana za pomocą flagi IFILTER_INIT IFILTER_INIT_INDEXING_ONLY, test zwalnia interfejs IFilter i ponownie wiąże go przed wykonaniem innego wywołania metody IFilter::Init.
Test spójności weryfikuje następujące warunki:
- Każda struktura STAT_CHUNK zwrócona przez metodę IFilter::GetChunk jest identyczna z odpowiednią STAT_CHUNK zwróconą w teście weryfikacyjnym.
- IFilter::GetChunk zwraca S_OK lub inną akceptowalną wartość zwracaną, taką jak FILTER_E_END_OF_CHUNKS, FILTER_E_LINK_UNAVAILABLE itd.
Nieprawidłowy test wejściowy
Program ifilttst.exe ponownie inicjuje interfejs IFilter z tymi samymi parametrami i wykonuje nieprawidłowy test wejściowy. Ten test przechodzi przez dokument, analizując go fragment po fragmencie, podczas wykonywania niepoprawnych wywołań funkcji, takich jak wywoływanie metody IFilter::GetValue, gdy bieżący fragment zawiera tekst. Test sprawdza wszystkie kody powrotne pod kątem zgodności ze specyfikacją IFilter.
Nieprawidłowy test wejściowy weryfikuje następujące warunki:
- Jeśli bieżący fragment zawiera tekst, IFilter::GetValue zwraca FILTER_E_NO_VALUES i wywołanie metody IFilter::GetText powiedzie się.
- Jeśli bieżący fragment zawiera wartość, IFilter::GetText zwraca FILTER_E_NO_TEXT i wywołanie metody IFilter::GetValue powiedzie się.
- Jeśli poprzednie wywołanie metody IFilter::GetText zwróciło FILTER_E_NO_MORE_TEXT, kolejne wywołania IFilter::GetText zwracają FILTER_E_NO_MORE_TEXT.
- Jeśli poprzednie wywołanie metody IFilter::GetValue zwróciło FILTER_E_NO_MORE_VALUES, kolejne wywołania IFilter::GetValue zwracają FILTER_E_NO_MORE_VALUES.
- Jeśli poprzednie wywołanie metody IFilter::GetChunk zwróciło FILTER_E_END_OF_CHUNKS, to kolejne wywołania IFilter::GetChunk będą zwracać FILTER_E_END_OF_CHUNKS.
Notatka
Test nieprawidłowych danych wejściowych porównuje struktury bieżących fragmentów z tymi zwróconymi w teście walidacji, aby upewnić się, że są identyczne.
Testowanie różnych konfiguracji filtru IFilter
Program ifilttst.exe zwalnia interfejs IFilter i ponownie wiąże, inicjując go tym razem z użyciem następnego zestawu parametrów. Test powtarza cykl: test weryfikacji, test spójności i nieprawidłowy test wejściowy, dopóki nie zostaną przetestowane wszystkie żądane konfiguracje IFilter określone w pliku ifilttst.ini.
Zapewnianie indeksowania zarejestrowanych elementów
Końcowy test twojego IFilter gwarantuje, że twój IFilter jest prawidłowo zarejestrowany i wywoływany do indeksowania elementów, które zarejestrowałeś do jego użycia. Za pomocą Menedżera wykazu można zainicjować ponowne indeksowanie lub użyć Menedżera zakresu przeszukiwania (CSM), aby skonfigurować domyślne reguły wskazujące adresy URL, które mają być przeszukiwane przez indeksator. Po zakończeniu indeksowania użyj interfejsu użytkownika usługi Windows Search, aby wyszukać ciąg w zawartości lub właściwościach elementów. Jeśli elementy zostały zindeksowane, będą wyświetlane w wynikach wyszukiwania.
Aby uzyskać więcej informacji na temat ponownego indeksowania, zobacz Korzystanie z Menedżera Katalogów oraz Korzystanie z Menedżera Zakresu Przeszukiwania. Przykładowy kod ReindexMatchingUrls przedstawia sposoby określania plików do ponownego indeksowania i sposobu. Przykładowy kod CrawlScopeCommandLine przedstawia sposób definiowania opcji wiersza polecenia dla operacji indeksowania menedżera zakresu przeszukiwania (CSM). Oba przykłady kodu są dostępne w witrynie GitHub.
Przykładowy plik dziennika
Na żądanie program Ifilttst.exe może utworzyć dziennik zawierający opis kroków, które wykonuje podczas wykonywania. Poniższe przykłady to fragmenty z pliku dziennika z szczegółowością ustawioną na najwyższą możliwą wartość 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.
Pierwszy wiersz to komunikat informacyjny wskazujący, że nowa konfiguracja została załadowana z pliku ifilttst.ini. Wiersz (3) wskazuje nazwę sekcji w pliku ifilttst.ini, z którego odczytano aktualną konfigurację. Wiersze od (4) do (7) zawierają listę parametrów dla IFilter::Init. Wiersze rozpoczynające się od INFO
to komunikaty informacyjne dotyczące powiązania IFilter oraz rozpoczęcia testu weryfikacyjnego. Wiersze rozpoczynające się od PASS
to wiadomości dotyczące określonych testów, które zakończyły się pomyślnie.
Linia w poniższym przykładzie dziennika jest ostrzeżeniem. Ostrzeżenia zwracają uwagę na zachowanie IFilter, które jest problematyczne, chociaż legalne. To ostrzeżenie wskazuje, że metoda IFilter::GetChunk zwróciła fragment tekstu, który nie zawiera tekstu.
WARNING-First call to GetText() returned FILTER_E_NO_MORE_TEXT.
Poniższy przykładowy komunikat o błędzie wskazuje, że IFilter emitował fragment, którego nie zażądano.
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
W przypadku tego przykładowego komunikatu o błędzie IFilter wyemitował fragment z identyfikatorem PID 0x5
. Inspekcja sekcji [Test1]
w ifilttst.ini wykazała, że IFilter został skonfigurowany do nie emitowania fragmentów z tym identyfikatorem PID. Jeśli na przykład w wpisie Flags nie określono ani IFILTER_INIT_APPLY_INDEX_ATTRIBUTES, ani IFILTER_INIT_APPLY_OTHER_ATTRIBUTES, a cAttributes wynosiło 0, to IFilter będzie emitować tylko fragmenty z identyfikatorem PID 0x13
, odpowiadające PID_STG_CONTENTS.
Przykładowy plik zrzutu
Na żądanie program Ifilttst.exe może utworzyć zrzut zawierający znalezione fragmenty i ich zawartość. Poniższy przykład to fragment takiego pliku zrzutu.
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
Dziewięć pierwszych wierszy opisuje bieżącą strukturę fragmentu. Identyfikator GUID i PID odpowiadają PSGUID_STORAGE / PID_STG_CONTENTS. Jest to fragment zawierający zwykły tekst. Tekst znajduje się w następującej strukturze fragmentów:
10. This is an HTML IFilter test page
Następny fragment, zaczynając od wiersza 11, ma inny identyfikator GUID odpowiadający HTML IFilter
i inny identyfikator PID odpowiadający HREF HTML. Jest to wewnętrzna właściwość typu wartości wyeksportowana przez HTML IFilter
.
Następny fragment, począwszy od wiersza 21, ma ten sam identyfikator GUID i PID, ale jego stan fragmentu jest VALUE
zamiast TEXT
. Należy pamiętać, że tekst w tych dwóch ostatnich fragmentach jest taki sam jak w przypadku pierwszego fragmentu. Ale ponieważ IFilter jest przeznaczony dla trzech atrybutów (zwykły tekst, HTML HREF jako tekst i HTML HREF jako wartość) do zastosowania do tej frazy, wyniki są emitowane w trzech oddzielnych fragmentach.
Dodatkowe zasoby
- Przykładowy kod IFilterSample, dostępny na GitHubie, pokazuje, jak utworzyć klasę bazową IFilter do implementacji interfejsu IFilter.
- Aby zapoznać się z omówieniem procesu indeksowania, zobacz Proces indeksowania.
- Aby zapoznać się z omówieniem typów plików, zobacz Typy plików.
- Aby wysłać zapytanie o atrybuty skojarzenia pliku dla typu pliku, zobacz PerceivedTypes, SystemFileAssociations i Application Registration.
Tematy pokrewne
tworzenie programów obsługi filtrów
Informacje o programach obsługi filtrów w usłudze Windows Search
najlepsze rozwiązania dotyczące tworzenia programów obsługi filtrów w usłudze Windows Search
zwracanie właściwości z programu obsługi filtrów
programy obsługi filtrów dostarczane z systemem Windows