Building a recipe application using Vista and .NET 3.0 (Part V: Utilizing Windows Search in .NET applications)

Apologies for the delay of this post, I’ve been busy with MIX07. Charles Torre and I organized the MIX07 Sandbox this year, and it was a great success. This year we raised the bar with regards to the types of people that a Hands on lab was interesting to: Business people, Designers, as well as Developers. We also increased the usefulness of the Sandbox in this Sky Server for which all MIX07 attendees have access. The experimental OpenMic, the place for any MIX attendee to talk about whatever they wanted, was also popular. Next year, we will raise awareness of the OpenMic and provide a way for people to sign up for OpenMic prior to the event.

Making the ECB file type searchable from Explorer

It’s easy to make the Electronic Cookbook file-type fully searchable in Windows Vista by making changes in the “Indexing Options” applet. You can find this in the control panel, or simply typing “Index” in the Start Menu Search box and choosing “Indexing Options.” (Open up the Start Menu by pressing the Windows key on your keyboard.)

Fig. 1 – Windows Start Menu.

Fig. 1 – Windows Start Menu.

 

 

Caution: When changing some indexing settings (such as changing a filter) Windows will re-index the content. This operation could take a few hours depending on the amount of content on your machine. Be aware that you will not be able to fully search your hard-drive until it is finished re-indexing.

Click the “Advanced Options” button and switch to the “File Types” tab.

 

Fig. 2 – Windows Vista Indexing Options, Advanced Options dialog

Fig. 2 – Windows Vista Indexing Options, Advanced Options dialog

By default most files-types are set to only index file properties exposed to the shell, however for our scenario we want to be able to search the entire file contents. If you’ve installed the ECB ThumbnailProvider you will see an .ecb entry, choose the “Index Properties and File Contents” radio button for the ECB file-type and click OK. This enables searching the text contents of the file, in addition to properties that are exposed to the Windows shell. If we had a PropertyHandler written for this file type, we could alternately avoid exposing all the text content and only make particular properties searchable. For example this might be useful if we wanted to only search on the “Tags” that are assigned to a file.

 

 Incidentally, if you want to search your CSharp (.cs) files for code you would make this same change for the .cs file-type. You’d also need to ensure that the folders that your content resides in is marked for indexing. By default everything that is under the \users\<username> folders is automatically marked for indexing, but if you have a separate location on your hard disk for the content that you want searched, you may have to explicitly set the Indexing engine to index those files. This can be set from the same Indexing Options applet, but you would click the Modify button and check the appropriate folders on your drive.

 

Fig. 3 – Indexing Options Dialog

Fig. 3 – Indexing Options Dialog

 

When Windows has finished indexing, you should be able to type any word that is contained in an Electronic Cookbook (ECB) file, and have it surface in the search results in the Start Search box on the Start Menu. Try typing “Chicken” and for example “Tikka Masala.ecb” recipe should appear under the “Files” group.

 

Fig. 4 – Start Menu displaying indexed content

Fig. 4 – Start Menu displaying indexed content

 

Using Windows Search from within an application

So now let’s take a look at doing a Windows Search programmatically.  Windows Search has provided an OleDB provider, which makes programming against the Windows Search engine a cinch.

 

static string connectionString = @"Provider=Search.CollatorDSO;Extended Properties='Application=Windows'";

 

Then we manually construct the query. There are API’s that can help to construct a Query automatically, which I do not use in this sample (see AQS below)

 

Query = "SELECT \"System.FileName\", \"System.Rating\", \"System.Keywords\", \"System.ItemAuthors\", \"System.ItemPathDisplay\" FROM SYSTEMINDEX..SCOPE() WHERE \"System.ItemType\" = '.ecb' AND CONTAINS('" + searchstring + "')";

 

In this sample we take the resulting dataset from an OleDBDataReader and turn it into a collection of string arrays. Our recipe application then consumes that. See all the search code that we used for the Electronic Cookbook application here.

 

The tricky part is determining which particular properties that you need to care about. A “select *” does not work with Windows Search, so it’s a hit and miss search to see if any of the possible valid properties return anything of value. Here’s an extensive list of all the Shell properties that are available. The ones that I am working with in this application are located in the “Core” properties:  System.Filename, System.Keywords, System.Rating, System.Authors, and System.ItemType.

 

Windows Search 3.x and AQS

To read more about Windows Search see Catherine Heller’s blog in general https://blogs.msdn.com/cheller. Some Windows Search documentation is available on MSDN and here’s an SDK that shows C++ samples of how to program against Windows Search 3.x, that also includes a useful managed library.  Also of potential interest for our recipe application is Advanced Query Syntax (AQS) which you can read about here and Catherine blogs about here and here.

 

In the next blog post we’ll discuss creating a Windows Property Handler written in C++ that is designed to work with Electronic Cookbook files.