Programmatic use of windows search

I recently wanted to add a photo search capability to my Timeline program and discovered that you can open a windows explorer with a custom search. You can also type these searches directly into the address bar in a windows file explorer.

The key is the search-ms protocol. It allows programs (like windows explorer) to directly query the windows search index. The parameters to this command are somewhat obscure, but it is very flexible and it can be used to perform any search that you could perform with the graphical search function in the windows file explorer.

For my application, I wanted to search for all photos that were taken between two dates (the start and end date of an event on my timeline). The idea is to quickly find all the photos that I took on a trip or at an event.

The general syntax for the search-ms command is:

search-ms:query=<query string>&
          crumb=<location and display parameters>&
          syntax=<NQS or AQS(default)>

The query string can be any valid SQL or AQS search. For my application I wanted to query on the date my photo was taken which windows stores as “datetaken” and I wanted to query over a range of dates. Dates have to be in the YYYY-MM-DD format, and a range is specified with “..”.

I used the crumb specifier to target a just the “My Pictures” special folder. To specify a location you put crumb=location:<URL encoded path>. For a special folder you do crumb=location:shell%3a<folder name>.

So my final query string is:

search-ms:query=datetaken:2015-01-01..2016-01-01&crumb=location:shell%3aMy%20Pictures

You can type or copy this into your search bar to see all the photos you took in 2015.

From C# you can start a process by giving the name of a file that has a default program association. So launching a file explorer with a custom search is as easy as:

System.Diagnostics.Process.Start("search-ms:query=datetaken:" + 
  Start().ToString("yyyy-MM-dd") + ".." + End().ToString("yyyy-MM-dd") +
  "&crumb=location:shell%3aMy%20Pictures");