How to use Windows Search Service in c#

user4031277 picture user4031277 · Dec 17, 2015 · Viewed 9.8k times · Source

I'm working on an application, an user can search for files or folders either on the local computer or on the network. I am using DirectoryInfo.GetDirecotories().

  1. But I also want to add the functionality that windows 7 uses for searching, I believe that uses indexing. I also saw Windows Searching Service on msdn, but I'm not sure which way is best: querying the indexed catalog or using the search service. Any suggestions?
  2. I was wondering if anyone can give me a small example in C# that searches the indexed catalog.

Thanks in advance!

Answer

bokibeg picture bokibeg · Dec 17, 2015

See the below example:

static void Main(string[] args)
{
    var connection = new OleDbConnection(@"Provider=Search.CollatorDSO;Extended Properties=""Application=Windows""");

    // File name search (case insensitive), also searches sub directories
    var query1 = @"SELECT System.ItemName FROM SystemIndex " +
                @"WHERE scope ='file:C:/' AND System.ItemName LIKE '%Test%'";

    // File name search (case insensitive), does not search sub directories
    var query2 = @"SELECT System.ItemName FROM SystemIndex " +
                @"WHERE directory = 'file:C:/' AND System.ItemName LIKE '%Test%' ";

    // Folder name search (case insensitive)
    var query3 = @"SELECT System.ItemName FROM SystemIndex " +
                @"WHERE scope = 'file:C:/' AND System.ItemType = 'Directory' AND System.Itemname LIKE '%Test%' ";

    // Folder name search (case insensitive), does not search sub directories
    var query4 = @"SELECT System.ItemName FROM SystemIndex " +
                @"WHERE directory = 'file:C:/' AND System.ItemType = 'Directory' AND System.Itemname LIKE '%Test%' ";           

    connection.Open();

    var command = new OleDbCommand(query4, connection);

    using (var r = command.ExecuteReader())
    {
        while (r.Read())
        {
            Console.WriteLine(r[0]);
        }
    }

    connection.Close();

    Console.ReadKey();
}

It's using OLE DB api to connect to the indexer service and use a SQL-like syntax to search System objects in its SystemIndex table. You have 4 example queries which do different things. All example queries will search in the c:\ folder for items that contain Test in their names.

You can search for files, folders mails and possibly other media (depending on OS) on local or other machines. From what I have researched network drives are not supported since they can't be indexed but you can connect to other machines for which I assume RPC is used in the background which means you have to supply network credentials using a different api (e.g. System.Net).

Note that for any of this to work your indexing must be fully operational on the target machine (which it is by default). The api is corresponding to whatever you specify in your Indexing Options. This is the screen in question:

indexing options

The full list of properties for the System object can be found here: Property System Reference. This object contains things such as URL, Path, Name, Date etc.

More interesting examples using different predicates (e.g. scope and directory) can be found here: Windows Vista Search Syntax. There is also a crude MSDN documentation: SCOPE and DIRECTORY Predicates

I recommend you check out the documentation because you can do a lot of stuff with this api.