Wednesday, 07 May 2008

Everyone who uses Windows Vista knows the Windows Desktop Search (WDS), which can be used from almost everywhere (StartMenu, Control Panel, Explorer etc). Wouldn't it be cool to use this mechanism programmatically in your own .NET application? For example, if you have tons of documents in your company (on a Windows Server 2003 or higher) ... then you can search through the content of all the documents and provide the results it in an intranet web application.

Of course you can do this already, but

a) you need to download and install the Windows Search SDK
b) then you have to create an interop assembly by importing a special type library (see [1] and [2])
c) you need knowledge about the advanced query syntax (see [3])

I know most of the developers are lazy, so i created a WindowsSearchHelper [4], which is of course only a wrapper around the SearchQueryHelper shipped in the SDK. But with a little more comfort, e.g. it encapsulated the initialization of all necessary stuff or holds all search parameters in enumerations.

So, what is to do?
1) Download the dll from [4]
2) Reference it within your .NET Project
3) Write:

   1: WindowSearchHelper wsh = new WindowSearchHelper();
   2: wsh.MaxResults = 100;

4) Then you can start to add your seach options. There are 4 Methods to add the search- and result parameters

   1: //Add the search return columns (= the result informations)
   2: wsh.AddSearchReturnColumn(SystemShellProperties.System_ItemNameDisplay);
   3:  
   4: //you can add special boolean parameters like 
   5: wsh.AddSearchBooleanParameter(SearchBooleanParameters.HasAttachment, true);
   6: wsh.AddSearchBooleanParameter(SearchBooleanParameters.IsDeleted, false);
   7:  
   8: //you can specify the file kind, special dates and/or special data stores
   9: wsh.AddSearchTypesAndDates(SearchTypesAndDates.CommonFileKinds_Person);
  10: wsh.AddSearchTypesAndDates(SearchTypesAndDates.DataStore_Mapi);
  11: wsh.AddSearchTypesAndDates(SearchTypesAndDates.Dates_Today);
  12:  
  13: //and you can add common search parameters 
  14: wsh.AddSearchValueParameter(SearchValueParameters.Common_Ext, "*.gif", true);
  15: wsh.AddSearchValueParameter(SearchValueParameters.Music_Artist, "Daft Punk", false);
  16: wsh.AddSearchValueParameter(SearchValueParameters.Documents_Slides, ">20", false);

5) Start the Search and handle the returned dataset

   1: DataSet ds = wsh.Search("SearchString");

Note! Not all of the possible combinations make sense.  Here are some small valid examples
a) search for pdf documents from the last week

   1: wsh.AddSearchTypesAndDates(SearchTypesAndDates.CommonFileKinds_Docs);
   2: wsh.AddSearchTypesAndDates(SearchTypesAndDates.Dates_LastWeek);
   3: wsh.AddSearchValueParameter(SearchValueParameters.Common_Ext, "pdf", true);

b) search for music attached in e-mails

   1: wsh.AddSearchTypesAndDates(SearchTypesAndDates.CommonFileKinds_Music);        
   2: wsh.AddSearchBooleanParameter(SearchBooleanParameters.IsAttachment, true);

c) search for pictures

   1: wsh.AddSearchTypesAndDates(SearchTypesAndDates.CommonFileKinds_Pictures);

 
d) Finally, a whole Example: Search and show me all the emails i got yesterday
   1: private void SearchLastEMails()
   2: {
   3:  
   4:         WindowSearchHelper wsh = new WindowSearchHelper();
   5:         wsh.MaxResults = 100;
   6:  
   7:         //search for all emails from yesterday
   8:         wsh.AddSearchTypesAndDates(SearchTypesAndDates.CommonFileKinds_EMail);
   9:         wsh.AddSearchTypesAndDates(SearchTypesAndDates.Dates_Yesterday);
  10:  
  11:         //add the return values almost like in the start menu
  12:         wsh.AddSearchReturnColumn(SystemShellProperties.System_ItemName);
  13:         wsh.AddSearchReturnColumn(SystemShellProperties.System_DateModified);
  14:         wsh.AddSearchReturnColumn(SystemShellProperties.System_ItemTypeText);
  15:         wsh.AddSearchReturnColumn(SystemShellProperties.System_ItemFolderPathDisplayNarrow);
  16:         wsh.AddSearchReturnColumn(SystemShellProperties.System_Category);   
  17:         
  18:         //search and bind the results
  19:         DataSet dataSet = wsh.Search(TextBox1.Text);
  20:  
  21:         GridViewResults.DataSource = dataSet;
  22:         
  23:  
  24:         //dynamically add the columns in the grid
  25:         if (dataSet.Tables.Count > 0)
  26:         {
  27:             GridViewResults.Columns.Clear();
  28:             foreach (DataColumn column in dataSet.Tables[0].Columns)
  29:             {
  30:                 BoundField boundField = new BoundField();
  31:                 boundField.DataField = column.ToString();
  32:                 boundField.HeaderText = column.ToString();
  33:                 GridViewResults.Columns.Add(boundField);
  34:             }
  35:             GridViewResults.DataBind();
  36:         }        
  37: }

If you want, then use it on your own risk ... i just tested it on some vista machines and a Window Server 2008. But i give no warranty that it works everywhere. Have a nice day!

[1] http://www.devx.com/VistaSpecialReport/Article/33767/1954
[2] http://ashishsharmasblog.blogspot.com/2008/03/blog-post.html
[3] http://msdn.microsoft.com/en-us/library/bb266512(VS.85).aspx
[4] WindowsSearchHelper.zip (24kb)

Wednesday, 07 May 2008 23:07:57 (GMT Daylight Time, UTC+01:00)  #    Comments [89]  | 

Theme design by Jelle Druyts

Pick a theme: