Udostępnij za pośrednictwem


Wyszukiwanie za pomocą interfejsu IDirectorySearch

Interfejs IDirectorySearch zapewnia wydajny interfejs o nieznacznym obciążeniu do wykonywania zapytań dotyczących danych katalogu lub katalogu globalnego. Interfejs IDirectorySearch COM może być używany tylko z tabelą wirtualną, a tym samym nie jest dostępny dla środowisk deweloperskich opartych na automatyzacji.

Aby wykonać wyszukiwanie

  1. Połącz z obiektem w katalogu.
  2. Wywołaj QueryInterface, aby uzyskać wskaźnikIDirectorySearch.
  3. Uruchom wyszukiwanie przy użyciu wskaźnika IDirectorySearch. Wywołaj metodę IDirectorySearch::ExecuteSearch i przekaż filtr wyszukiwania, żądane nazwy atrybutów i inne parametry.

Aby uzyskać więcej informacji na temat składni filtru wyszukiwania, zobacz Składnia filtru wyszukiwania.

Wykonywanie zapytań jest specyficzne dla dostawcy. W przypadku niektórych dostawców rzeczywiste wykonanie zapytania nie następuje, dopóki nie zostanie wywołana IDirectorySearch::GetFirstRow albo IDirectorySearch::GetNextRow. Interfejs IDirectorySearch współdziała bezpośrednio z filtrami wyszukiwania. Ani dialekt SQL, ani dialekt LDAP nie są wymagane.

Interfejs IDirectorySearch udostępnia metody wyliczania zestawu wyników, wiersz po wierszu. Metoda IDirectorySearch::GetFirstRow pobiera pierwszy wiersz i IDirectorySearch::GetNextRow przenosi Cię do następnego wiersza z bieżącego wiersza. Po osiągnięciu ostatniego wiersza wywołanie tych metod zwraca kod błędu S_ADS_NOMORE_ROWS. Natomiast IDirectorySearch::GetPreviousRow przenosi cię z powrotem o jeden wiersz. Wartość zwracana S_ADS_NOMORE_ROWS wskazuje, że osiągnięto ostatni wiersz zestawu wyników. Te metody działają na zestawie wyników przechowywanym w pamięci na kliencie. W związku z tym, gdy wykonywane są wyszukiwania stronicowane i asynchroniczne, a opcja _CACHE_RESULTS jest wyłączona, przewijanie do tyłu może mieć nieoczekiwane konsekwencje.

Po zlokalizowaniu odpowiedniego wiersza wywołaj IDirectorySearch::GetColumn, aby uzyskać elementy danych, kolumna po kolumnie. Dla każdego wywołania należy przekazać nazwę kolumny, która nas interesuje. Zwrócony element danych jest wskaźnikiem do struktury ADS_SEARCH_COLUMN. GetColumn przydziela tę strukturę dla Ciebie, ale musisz ją zwolnić, używając FreeColumn. Wywołaj CloseSearchHandle, aby ukończyć operację wyszukiwania.

Aby wykonać wyszukiwanie w katalogu

  1. Wiązanie z dostawcą LDAP. Może to być kontroler domeny lub dostawca wykazu globalnego.

  2. Pobierz interfejs IDirectorySearch COM poprzez wywołanie QueryInterface; ta operacja mogła zostać wykonana w kroku 1 podczas wstępnego powiązania.

    Opcjonalnie wywołaj SetSearchPreference, aby wybrać opcje obsługi wyników wyszukiwania.

  3. Wywołaj ExecuteSearch. W zależności od opcji ustawionych w SetSearchPreference może to spowodować lub nie rozpocząć wykonywania zapytania.

  4. Wywołaj GetNextRow, aby przenieść indeks wierszy (wewnętrzny do IDirectorySearch) do pierwszego wiersza.

  5. Odczytaj dane z wiersza przy użyciu GetColumn, a następnie wywołaj FreeColumn, aby zwolnić pamięć przydzieloną przez GetColumn.

  6. Powtarzaj Krok 5, dopóki wszystkie dane nie zostaną pobrane z wyniku wyszukiwania lub dopóki GetNextRow nie zwróci S_ADS_NOMORE_ROWS.

  7. Po zakończeniu wywołaj funkcje AbandonSearch i CloseSearchHandle.

Poniższy przykład kodu przedstawia ten scenariusz. Aby rozpocząć powiązanie z usługą ADSI, wywołaj funkcję ADsOpenObject.

HRESULT hr = S_OK; // COM result variable
ADS_SEARCH_COLUMN col;  // COL for iterations
LPWSTR szUsername = NULL; // user name
LPWSTR szPassword = NULL; // password
 
// Interface Pointers.
IDirectorySearch     *pDSSearch    =NULL;
 
// Initialize COM.
CoInitialize(0);

// Add code to securely retrieve the user name and password or
// leave both as NULL to use the default security context.
 
// Open a connection with server.
hr = ADsOpenObject(L"LDAP://coho.salmon.Fabrikam.com", 
szUsername,
szPassword,
ADS_SECURE_AUTHENTICATION,
IID_IDirectorySearch,
(void **)&pDSSearch);

Zapewnia to wskaźnik do interfejsu IDirectorySearch.

Teraz, gdy istnieje interfejs COM dla instancji IDirectoryInterface, wywołaj IDirectorySearch::SetSearchPreference.

Utwórz tablicę nazw atrybutów, aby przygotować się do wywołania funkcji IDirectorySearch::ExecuteSearch. Nazwy atrybutów są definiowane w schemacie usługi Active Directory. Aby uzyskać więcej informacji na temat definicji schematu, zobacz ADSI Schema Model. Wymienione nazwy atrybutów są zwracane, jeśli są obsługiwane przez obiekt, jako zestaw wyników wyszukiwania.

LPWSTR pszAttr[] = { L"description", L"Name", L"distinguishedname" };
ADS_SEARCH_HANDLE hSearch;
DWORD dwCount = 0;
DWORD dwAttrNameSize = sizeof(pszAttr)/sizeof(LPWSTR);

Teraz wywołaj funkcję ExecuteSearch. Wyszukiwanie nie jest uruchamiane, dopóki nie wywołasz metody GetNextRow.

// Search for all objects with the 'cn' property that start with c.
hr = pDSSearch->ExecuteSearch(L"(cn=c*)",pszAttr ,dwAttrNameSize,&hSearch );

Wywołaj GetNextRow, aby iterować wiersze w wyniku. Każdy wiersz jest następnie odpytywany pod kątem atrybutu "description". Jeśli atrybut zostanie znaleziony, zostanie wyświetlony.

LPWSTR pszColumn;
    while( pDSSearch->GetNextRow( hSearch) != S_ADS_NOMORE_ROWS )
    {
        // Get the property.
        hr = pDSSearch->GetColumn( hSearch, L"description", &col );
 
        // If this object supports this attribute, display it.
        if ( SUCCEEDED(hr) )
        { 
           if (col.dwADsType == ADSTYPE_CASE_IGNORE_STRING)
              wprintf(L"The description property:%s\r\n", col.pADsValues->CaseIgnoreString); 
           pDSSearch->FreeColumn( &col );
        }
        else
            puts("description property NOT available");
        puts("------------------------------------------------");
        dwCount++;
    }
    pDSSearch->CloseSearchHandle(hSearch);
    pDSSearch->Release();

Aby zakończyć wyszukiwanie, wywołaj metodę AbandonSearch.

Należy pamiętać, że jeśli rozmiar strony nie jest ustawiony, GetNextRow blokuje do momentu, gdy cały zestaw wyników zostanie zwrócony klientowi. Jeśli rozmiar strony jest ustawiony, GetNextRow blokuje, dopóki pierwsza strona (rozmiar strony = liczba wierszy na stronie) nie zostanie zwrócona. Jeśli rozmiar strony jest ustawiony, a zapytanie ma być sortowane i nie wyszukujesz co najmniej jednego indeksowanego atrybutu, wartość rozmiaru strony jest ignorowana, a serwer oblicza cały zestaw wyników przed zwróceniem danych. Powoduje to, że GetNextRow blokuje się do momentu ukończenia zapytania.

Notatka

Aby zmienić to zapytanie z wyszukiwania w katalogu na wyszukiwanie w wykazie globalnym, wywołanie ADsOpenObject jest zmieniane.

 

// Open a connection with the server.
hr = ADsOpenObject(L"GC://coho.salmon.Fabrikam.com", 
szUsername, 
szPassword, 
ADS_SECURE_AUTHENTICATION,
IID_IDirectorySearch,
(void **)&pDSSearch);