T-23: Suchen mit der Windows Shell

Gastposting von Oliver Scheer , Developer Evangelist - Windows, Silverlight und UI-Technologien bei der Microsoft Deutschland GmbH.

23_2Nur noch 23 Tage bis zum Launch von Windows 7.

Ein altes Sprichwort sagt: „Wer suchet, der findet.“. Warum lassen wir nicht unsere eigenen Anwendungen suchen? Windows 7 liefert die notwendige Search API dafür mit.

Um die Search API aus .NET-Code ansprechen zu können, ist wirklich nicht viel nötig. Man muss lediglich das Windows API Code Pack einbinden und schon kann in wenigen Zeilen der eigene Suchclient entwickelt werden.

Was man sucht und vor allem wo man sucht, ist jedem Entwickler selbst überlassen. Die Qualität der Suche hängt aber wesentlich von diversen Kriterien ab: So ist es ziemlich sinnlos nach Liedern ihrer Lieblingsband im System-Ordner von Windows zu suchen. Und Bilder vom letzten Firmenfest werden sie nicht in ihren Musikordnern finden. Es sei denn, sie haben eine sehr interessanten Organisationsstil.

Aus gutem Grund bietet die API daher auch die nötigen Konfigurationswerkzeuge für die Suche an. In welchen Typen von Ordner soll gesucht werden? Was für Daten suchen wir? Sollen alle Suchbegriffe oder zumindest ein Suchbegriff im Dokument gefunden werden? Handelt es sich um aktuelle Daten oder vor langer Zeit angelegte Dokumente?

Eine eigene Suchanwendung ist sehr schnell implementiert. Dafür sind lediglich zwei Bibliotheken aus dem Windows API Code Pack notwendig:

image

Die Methode zum Suchen:

private void StartSearch(string searchText)
{
// Erzeuge Suchbedingungen
SearchCondition searchCondition =
GetSearchCondition(searchText);
// Datum als weiteres Suchkriterium hinzufügen
SearchCondition dateCondition =
SearchConditionFactory.CreateLeafCondition(
SystemProperties.System.Title,
searchText,
SearchConditionOperation.ValueContains);
// Zusammensetzen der Suchbedingungen
SearchCondition finalSearchCondition =
SearchConditionFactory.CreateAndOrCondition(
SearchConditionType.Or,
false,
searchCondition,
dateCondition);

// Erzeuge einen ShellSearchFolder
ShellSearchFolder searchFolder;
if (ShellLibrary.IsPlatformSupported)
{
searchFolder = new ShellSearchFolder(
finalSearchCondition,
(ShellContainer)KnownFolders.DocumentsLibrary,
(ShellContainer)KnownFolders.PicturesLibrary,
(ShellContainer)KnownFolders.VideosLibrary);
}
else
{
searchFolder = new ShellSearchFolder(
finalSearchCondition,
(ShellContainer)KnownFolders.Documents,
(ShellContainer)KnownFolders.Pictures,
(ShellContainer)KnownFolders.Videos);
}

// DataList die die Ergebnisse anzeigt
_result.ItemsSource = searchFolder;
}

Die Methode GetSearchCondition ist folgendermaßen implementiert:

private SearchCondition GetSearchCondition(string searchText)
{
// Einzelne Suchbegriffe aus dem Textbilden
string[] words = searchText.Split(’ ‘);
// Das Suchergebnis ist erstmal leer
SearchCondition combinedPropertyCondition = null;
// Für jedes Word im Suchtext eine Suchbedingung erzeugen
foreach (string word in words)
{
// Erste Suchbedingung –> Suche nach Dateinamen
SearchCondition propertyCondition1 =
SearchConditionFactory.CreateLeafCondition(
SystemProperties.System.FileName,
word,
SearchConditionOperation.ValueContains);
// Zweite Suchbedingung –> Suche nache Keywords/Tags in Datei
SearchCondition propertyCondition2 =
SearchConditionFactory.CreateLeafCondition(
SystemProperties.System.Keywords,
word,
SearchConditionOperation.ValueContains);
// Wir wollen eine Oder-Bedingung für Tags oder Dateiname
SearchCondition tmpCombinedCondition =
SearchConditionFactory.CreateAndOrCondition(
SearchConditionType.Or,
false,
propertyCondition1,
propertyCondition2);

// Falls es bereits eine Suchbedingung gibt,

// verknüpfe die neue und die alten mit AND
if (combinedPropertyCondition != null)
{
combinedPropertyCondition =
SearchConditionFactory.CreateAndOrCondition(
SearchConditionType.And,
false,
combinedPropertyCondition,
tmpCombinedCondition);
}
else
{
combinedPropertyCondition = tmpCombinedCondition;
}
}
return combinedPropertyCondition;
}

Die Suche an sich wird über die Klasse ShellSearchFolder ausgeführt. Die Definition der Suchanfrage erfolgt über die SearchConditions. Welche Ordner durchsucht werden sollen, wird mit Hilfe von „KnownFolders“, so genannten bekannten Ordner definiert.

searchFolder = new ShellSearchFolder(
finalSearchCondition,
(ShellContainer)KnownFolders.DocumentsLibrary,
(ShellContainer)KnownFolders.PicturesLibrary,
(ShellContainer)KnownFolders.VideosLibrary);

Das Suchergebnis kann man nun visualisieren wie man möchte. Ich habe mich in diesem Beispiel auf eine einfache Liste beschränkt. Im Windows API Code Pack steht dazu eine vollwertige WPF-Visualisierung zur Verfügung.

Das Video des Tages

Get Microsoft Silverlight