How-to: Query Vista Search From Your App

Sign in to queue

Description

Ian Griffiths, dev trainer extraordinaire, recorded a series of "how-to" videos for us, each one demonstrating how to write code that takes advantage of a feature of the Windows Vista platform.  Here's the first in the series -- how to issues queries against the desktop search engine.

[Update: the second installment, How To: Use Vista's Power Management APIs To Be A Good Laptop Citizen is now up]

Embed

Download

Download this episode

The Discussion

  • User profile image
    jmazner

    Here are a few snippets of relevant source code from the demo:

    public partial class Window1 : Window
     {
      private ImageCollection _foundImages = null;
      private string[] _exifProperties = new string[] {
       "System.Photo.CameraManufacturer", "System.Photo.CameraModel",
       "System.Photo.FNumber", "System.Photo.ExposureTime", "System.Photo.FocalLength",
       "System.Photo.ExposureBias", "System.Photo.MeteringMode",
       "System.Photo.ColorSpace"};

      private string[] _generalProperties = new string[] {
       "System.Author", "System.Keywords", "System.File.Description"};

      private void OnSearch(object sender, RoutedEventArgs e)
      {
       string indexerConnString = "provider=Search.CollatorDSO.1;EXTENDED PROPERTIES=\"Application=Windows\"";
       using (OleDbConnection conn = new OleDbConnection(indexerConnString))
       {
        conn.Open();
        string keywordValue = SearchBox.Text;

        _foundImages.Clear();
        GetImageFileResults(keywordValue, conn);
        ImageListBox.DataContext = _foundImages;
       }
      }

      private void GetImageFileResults(string keywordValue, OleDbConnection conn)
      {

       try
       {
        System.Collections.Hashtable checkNames = new System.Collections.Hashtable();

        string sqlString = "Select \"System.Title\", " +
            "\"System.DisplayFolder\", \"System.DisplayName\" " +
            "FROM systemindex..scope() " +
                        "WHERE FREETEXT(\"System.CanonicalType\", 'JPG') "/* +
                            "AND CONTAINS(\"System.Path\", 'file:')"*/;
                    if (!string.IsNullOrEmpty(keywordValue))
                    {
                        sqlString += " AND (\"System.Keywords\" = SOME ARRAY ['" + keywordValue + "'])";
                    }

        OleDbCommand cmd = new OleDbCommand(sqlString, conn);

        using (OleDbDataReader reader = cmd.ExecuteReader())
        {

         while (reader.Read())
         {
          ImageInfo imageInfo = new ImageInfo();
          imageInfo.Title = reader.GetString(0);
                            string folder = reader.GetString(1);
                            string name = reader.GetString(2);
                            // workaround to ignore non-files
                            if (folder.Length < 2 || folder[1] != ':')
                                continue;
          imageInfo.ImagePath = System.IO.Path.Combine(
                                folder, name);
                            // Workaround to ignore peculiar files on non-existent
                            // volumes that build 5365 seems to return.
                            if (!System.IO.File.Exists(imageInfo.ImagePath))
                                continue;
                            if (imageInfo.ImagePath.Contains("Temporary Internet Files"))
                                continue;
          if (checkNames.ContainsKey(imageInfo.Title))
          {
           int index = (int)checkNames[(string)imageInfo.Title];

           if (_foundImages[index] != null)
           {
            if (_foundImages[index].Variations == null)
            {
             ImageCollection variationCollection = new ImageCollection();
             variationCollection.Add(imageInfo);
             _foundImages[index].Variations = variationCollection;
            }
            else
            {
             _foundImages[index].Variations.Add(imageInfo);
            }
           }

          }
          else
          {
           imageInfo.Variations = new ImageCollection();
           imageInfo.Variations.Add(imageInfo);
           int currentIndex = _foundImages.Count;
           checkNames.Add(imageInfo.Title, currentIndex);
           _foundImages.Add(imageInfo);

          }
         }

        }
       }
       catch (OleDbException)
       {
        // Not finding any results is ok.
       }

  • User profile image
    jmazner
    For more details about how to use desktop search, check out Catherine Heller's excellent blog entry
  • User profile image
    littleguru
    Is this going to be encapsulated in any way? I find it to rough to deal with the Windows database in this way.

    Btw. Is there a way to get the different columns of a document? I mean in the example with the pictures it is great, but for other documents?
  • User profile image
    footballism
    Good to see Ian's awesome screencast, but where can I get the source code of demo app shown in the video?

    Sheva
  • User profile image
    littleguru
    Let the sql injection begin:

    {"The ICommandWithParameters interface is not supported by the 'Search.CollatorDSO.1' provider.  Command parameters are unsupported with the current provider."}
  • User profile image
    littleguru
    footballism wrote:
    Good to see Ian's awesome screencast, but where can I get the source code of demo app shown in the video?

    Sheva


    Copy and past his second post?
  • User profile image
    Ion Todirel

    btw, how to extract/change metadata from files in Vista?

    EDIT: nevermind

  • User profile image
    zahadum
    this video file is corrupted. it starts choppy & then stalls. why? maybe C9 should be using a standard format like isma.tv
  • User profile image
    alinc
    Great sample, thanks for sharing it.

    The query is searching in the Windows Index database (FROM SYSTEMINDEX..SCOPE).
    If, let's say, I don't have my D: drive indexed, how do I perform a search on this drive as well. There is possible to have a syntax like this:

    SELECT "System.FileName" FROM "D:\"..etc?

    Thanks,
    Alin
  • User profile image
    shashanka_d

    I tried with a similar code. I was able to get the column name with reader.GetName(0) but the result set was not found. that is , when i say reader.GetString(0), i get the error saying there is no data in the row/column. i tried out with different keywords but still the same result. I also tried using the same keyword in the WDS, then i got some results. My prob is i am not able to get the same result programmatically. The query i am using is:

    SELECT DocTitle FROM systemindex..scope() WHERE CONTAINS('" + "Choose" + "')".

    here i am searching for the keyword "Choose".

    can neone pls help me on this..

  • User profile image
    JoyceSachs

    It's not working with me. I wonder what is wrong with my computer. Steam Generator Irons

  • User profile image
    son2best

    @JoeySachs that's becuase you have windows 7 not windows vista maybe. Mobile Phone Recycling

Add Your 2 Cents