It's been too long since I blogged about Windows Desktop Search (WDS) 3.0 in Windows Vista. This post is current with RC2 (build 5744). Since I last posted, WDS 3.0 is now also available for XP and 2003. This is awesome since you can develop great search-enabled applications to run on any modern desktop or server.
There is a COM interface for search. More information is in the Windows SDK Help file (User Interface | Windows Shell | Windows Desktop Search (WDS) 3.0). You don't need to use the search API though. The good news, in my opinion, is that you can just use OLE DB interfaces in any programming environment. Have fun in classic VB, managed code, C++, whatever!
If you are using the OLE interface, you will need a connection string. It's changed since the last time I blogged about it. You'll want to specify:
Provider=Search.CollatorDSO;Extended Properties='Application=Windows';
If you want to use the OLE DB API from C#, you can specify it as:
OleDbConnection conn = new OleDbConnection("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';");
Be sure to include:
using System.Data.OleDb;
The reason I love the OLE interface, is that desktop search is as easy as any other SQL query now. I've wanted the ability to query the filesystem as a database for a long time. You can search based on all sorts of property values (including plain old filename!), return a multitude of columns, and even search within the contents of the file, all without ever opening an actual file. The list of shell properties can found in the SDK help file at User Interface | Windows Shell | Shell Reference | Shell Properties.
A very simple example would be:
SELECT FileName, System.Size FROM systemindex..scope() WHERE System.Size > 1048576
This query would find all entities with a size greater than 1MB, and return the file name and size of the file. You can also add an ORDER BY clause if you need it. Notice the "systemindex..scope()" clause. This is the name of the WDS search "table". You can even prepend it with another machine name "OTHERMACHINE..systemindex..scope()" though you will need to do some extra configuration for that to work.
You can use LIKE in the WHERE clause if you want to specify simple expressions, but for more power, use the CONTAINS or FREETEXT predicates. These let you search either properties or the actual contents of a file. The format of either statement can be specified one of three ways:
- CONTAINS | FREETEXT ('<searchString>') full-text search of the file contents
- CONTAINS | FREETEXT (<column>, '<searchString>') limits search to a given property/column
- CONTAINS | FREETEXT (* , '<searchString>') performs full-text search on all properties and file contents
Note that if you have a search string of more than one word, you'll need double quotes -- within the single quotes. Yeah, it looks weird. So as an example, to search for "static public void" in all files, you could use:
SELECT FileName FROM systemindex..scope() WHERE CONTAINS(' "static public void" ')
The choice of CONTAINS or FREETEXT is simply whether or not you need the rank of each search result. If you use FREETEXT, you get the real rank. Otherwise, it's just 0 or 1000 for no match or math. To return the actual rank in your SELECT clause, add System.Search.Rank in your column list. Note also that search terms are case-insensitive.
The last thing to know, is that you can actually scope your search to a given folder, and/or subfolders. Typically, a search is across the entire index, but your UI might provide a folder selection, or maybe your application is restricted to some given folder. If you want a folder and all subfolders, use SCOPE. For example:
SELECT FileName FROM systemindex..scope() WHERE SCOPE='file:C:/Users/User1'
If you only want a single folder and not its subfolders, use DIRECTORY:
SELECT FileName FROM systemindex..scope() WHERE DIRECTORY='file:C:/Users/User1'
Some of the columns in the SDK don't seem to work (System.DisplayType for one). I don't know if this is because it just isn't filled in for all entries, or it just doesn't work via OLE, or what it is. So many do work though. I still need to do some more research. I'm sure it all makes sense once you figure it out!
Give the search functionality a try. You can search for files, documents (Office/Word, etc), contacts, media, any file via metadata properties or file contents with no actual file I/O. This should really allow for some powerful user interfaces. This should be fun!
Additional information:
posted @ Sunday, November 05, 2006 1:22 PM